Автоматизоване редагування частинок в комп`ютерній графіці

[ виправити ] текст може містити помилки, будь ласка перевіряйте перш ніж використовувати.

скачати

Введення

Сьогодні жоден із сучасних фільмів, які виходять на екран, жодна комп'ютерна гра, не обходиться без візуальних ефектів. Для того щоб привернути увагу вимогливого споживача створюються карколомні трюки і неймовірні ефекти.

Зазвичай над створенням візуальних ефектів працює цілий штат професіоналів в області комп'ютерної графіки та відеомонтажу. Використання при редагуванні відеоматеріалу передових технологій дозволяє додавати до фінальної картинку нові об'єкти, "вирізати" невдало попала в кадр деталь і багато іншого.

З появою тривимірної комп'ютерної графіки стало можливим використовувати практично будь-яку декорацію. Але, незважаючи на те, що спецефекти, які можна спостерігати в сучасних фільмах, здаються дуже складними, на створення багатьох з них іде набагато менше часу, ніж може подумати непідготовлений глядач.

Безумовно, використання тривимірної анімації - це гарантія того, що оброблений відеоматеріал або ігрова сцена, прораховуються в реальному часі, буде виглядати захоплююче. Однак, для того щоб отримати складний комп'ютерний ефект, потрібно дуже багато ресурсів. До того ж, прорахунок складних тривимірних сцен може зайняти немало часу. Існує безліч прийомів, використовуючи які можна отримати ті ж спецефекти з набагато меншими витратами, як часу, так і сил.

Багато ефекти в тривимірній графіці створюються за допомогою часток. Це і бризки води, і іскри бенгальського вогню, і розлітаються уламки будинку, що вибухнув автомобіля. За допомогою систем частинок одночасно створюється велика кількість однакових об'єктів, поведінкою яких можна легко управляти. Для створення, редагування та інтеграції в кінцеве додаток ефектів часток використовуються спеціальні програми - редактори частинок. На відміну від професійних пакетів для роботи з 3 D, вони зазвичай містять заздалегідь прораховані алгоритми поведінки частинок. Цим пояснюється їх швидкодію (зазвичай такі програми працюють в режимі реального часу).

Розроблений в рамках даної роботи програмний засіб "Easy Particles "є нескладним варіантом редактора частинок, що дозволяє оперувати низкою фізичних сил при програмуванні ефектів частинок. До основних його переваг можна віднести:

- Це програмне засіб є повністю безкоштовним, на нього не потрібно купувати комерційну ліцензію;

- На відміну від професійних пакетів роботи з частинками, навчитися працювати з даними редактором можна буквально за кілька хвилин;

- При цьому є створення складних, багатоступеневих ефектів, з використанням інтуїтивно-зрозумілої багатоступінчастої схеми;

- Використання графічного конвеєра OpenGL дозволило максимально прискорити процес розрахунків, так що висновок графіки в режимі реального часу можливий при дуже великих кількостях полігонів;

- Низькі вимоги, стабільність і простота настройки і роботи;

- Зручний графічний користувальницький інтерфейс;

У даній пояснювальній записці представлено докладний опис розробленого редактора частинок.

Звіт складається з шести розділів.

У розділі "Постановка завдання" описується предметна область з виділенням ключових абстракцій, формулюються вимога до задачі, обгрунтовується вибір інструментів реалізації завдання і міститься короткий огляд існуючих програм аналогічного характеру.

У розділі "Проектування і реалізація завдання" наводиться список класів з їх описом, розглядається фізична і логічна організація даних, дається опис концептуального прототипу, а також наводяться функції й елементи керування, якими оперує програма.

У розділі "Тестування" проводиться аналіз надійності програми, приклади тестових результатів, реакція програми на виняткові ситуації, аналіз отриманих результатів.

У розділі "Застосування програми" наводиться призначення програми з областю застосування, описується апаратно-програмний комплекс для нормального функціонування програми, система допомоги, розбирається інсталяція програми, діалог з користувачем.

У розділах "Оптимізація зорового взаємодії оператора з засобами відображення інформації па основі ЕЛТ", "Обгрунтування економічної доцільності розробки ПС" Easy Particles "" представлені відомості, задані для кожного розділу відповідно.

1. Постановка завдання

1.1 Вимоги до розробляється програмного засобу

Розроблюване програмний засіб має здійснювати такі основні функції:

- Управління динамічним набором емітерів (систем частинок);

- Управління частками кожного емітера;

- Управління загальними параметрами малювання;

- Введення і виведення даних на зовнішні носії;

- Висновок довідкових даних про розробника, способи використання програмного засобу;

Програмний засіб має забезпечувати оперування якомога більш повним набором характеристик емітерів, в той же час без перевантаження зайвими другорядними параметрами. При цьому, параметри не повинні вступати в протиріччя один з одним (наприклад, дублювання значної частини функціональності одного параметра - іншим). Інтерфейс повинен бути продуманим, без зайвих елементів. Він має відповідати принципу: створення простого ефекту - легко, а складного - можливо. Основні два принципи реалізації - простота і функціональність.

Вхідними даними додатка є параметри емітерів, що задаються користувачем, параметри режиму малювання.

Вихідними даними є відображаються у вікні виводу редактора, або в заданому вікні заданого програми, графічні об'єкти (частки), що трансформуються під впливом заданих сил, також виводяться у файл дані.

1.2 Обгрунтування актуальності теми ДП

Темою дипломного проекту була вибрано автоматизоване редагування частинок в комп'ютерній графіці. Вибір був зроблений відповідно до аналізу тенденцій що склалися останнім часом у світі комп'ютерної графіки, а також по наявності деяких особистих професійних прагнень.

Останнім часом створення складних графічних анімаційних ефектів з використанням спеціалізованих пакетів програмних засобів отримало найширше розповсюдження, як в організаціях, так і серед звичайних користувачів домашніх комп'ютерів. При цьому, на тлі великої кількості складних і дорогих комерційних рішень практично відсутні більш загальні і прості безкоштовні варіанти редакторів, призначених для початківців. Метою розробки було кілька заповнити цей пробіл. Адже часто дизайнерові графічного додатку, будь то гра, або що б то не було ще, потрібно швидко створити відносно нескладний ефект (або його начерк) і відразу ж перейти до виконання інших, більш пріоритетних на даний момент задач. Замість цього, він часто змушений витрачати багато часу на вивчення документації складних програмних продуктів, створювати в рамках свого навчання тестові приклади, і т.п. Завдяки даному програмному засобу, однак, завдання швидкого створення ефектів частинок цілком реалізовується не тільки для професійного дизайнера комп'ютерної графіки, але й для звичайного любителя, який здійснює своє перше знайомство з цими додатками.

1.3 Огляд існуючих рішень

На сьогоднішній день існує безліч програм для роботи з системами частинок. Ось деякі найбільш популярні з них:

a) ParticleIllusion;

б) Trapcode Particular;

в) Magic Particles;

Продукт компанії Wondertouch [10] ParticleIllusion на сьогоднішній день є, мабуть, найбільш всеохоплюючим засобом створення ефектів частинок. Спочатку включає досить велику бібліотеку безкоштовних ефектів, оновлювану кожен місяць. Має високу розширюваністю (підключення додаткових емітерів, наприклад).

Trapcode Particular - вбудований (необов'язковий) модуль для пакету програм Adobe After Effects, призначений для редагування частинок, розроблений компанією Trapcode [11]. Трохи менш широкий за можливостями, ніж ParticleIllusion, до того ж вона вимагає для роботи встановленого Adobe After Effects.

Magic Particles - російський генератор частинок компанії Астралакс [12]. Дозволяє швидко і наочно створювати візуальні спецефекти на основі систем частинок. Основна перевага Magic Particles - миттєве відображення всіх змін без тривалого процесу візуалізації. Хоча те ж можна сказати і про ParticleIllusion. Аналогічно, до складу Magic Particles входить близько сотні готових зразків, які можна використовувати як є або змінювати за своїм потребам. Хоча за багатьма аспектами функціональності даний продукт поступається ParticleIllusion, до нього постійно виходять оновлення з виправленнями та доповненнями.

Все, за винятком останнього, перераховані редактори частинок поширюються платно.

1.4 Цілі і завдання проекту

Основним завданням є розробка редактора частинок, що дозволяє, на відміну від перерахованих вище програмних продуктів, не витрачаючи великого часу на читання документації, створювати нескладні ефекти. Це повинно дозволити залучити велику кількість користувачів непрофесіоналів до використання програми, в тому числі з метою ознайомлення з основними прийомами по створенню ефектів частинок.

Для більшої відкритості та можливості ручного редагування вихідні файли редактора повинні мати формат XML. У даній (початковою) версії редактора допускається також зберігання в тому ж вихідному файлі інших, додаткових параметрів проекту. У майбутніх версіях, можливо, буде здійснено перехід на многофайловую систему зберігання даних проекту, для забезпечення більшої ясності при їх ручній обробці.

Висновок результуючої графічної інформації має здійснюватися у вікно редактора. Однак при цьому повинна бути реалізована можливість підключення та використання вихідних даних редактора (створених ефектів) до зовнішніх графічним додатками.

Іншим важливим завданням є розробка програми з можливостями подальшого розширення. Потрібно відзначити, що розробляється в рамках дипломного проектування програмний засіб є прототипом, які реалізують лише основні функціональні можливості програм даного класу. Тому необхідно подбати про майбутніх модифікаціях основної функціональності, можливості легкого додання нових параметрів, а також підтримці багатоплатформності (підтримка Mac OS X). При цьому дуже важливим залишається питання розробки такого користувальницького графічного інтерфейсу, щоб у нього можна було легко і без шкоди для зручності роботи дизайнера інтегрувати нові елементи, пов'язані з описаними вище новими можливостями. Це дуже важливе завдання, тому саме опрацюванні графічного користувацького інтерфейсу слід приділити максимум часу при розробці програмного засобу. Більш докладно про майбутні плановані розширення редактора буде сказано нижче.

Таким чином, метою роботи є розробка доступного, легко розширюваного і простого у використанні редактора частинок.

1.5 Опис програмно-алгоритмічного забезпечення вирішення поставленого завдання

1.5.1 Середовище для проектування та розробки програмних продуктів Microsoft Visual Studio 2005

Microsoft Visual Studio - лінійка продуктів компанії Microsoft, що включають інтегроване середовище розробки програмного забезпечення і ряд інших інструментальних засобів. У їх число входять редактори і компілятори мов Visual Basic. NET, Visual C + +, Visual C # і деякі інші. Також, що дуже важливо, Visual Studio пропонує докладну інформацію про бібліотеки і мови, включених в пакет, в MSDN - інформаційної бібліотеці по продуктах Microsoft, з можливістю отримання недостатньої інформації з Інтернету. Будь-який програміст, що створює програми для Windows, досить швидко переконується в абсолютній необхідності даного засобу при розробці. Також потрібно відзначити, що Microsoft Visual Studio побудована в архітектурі, що підтримує можливість використання доповнень від сторонніх розробників, що дозволяє розширювати можливості середовища розробки. Більш докладну інформацію про даному пакеті можна отримати на офіційному сайті виробника [13] і в Інтернеті.

Середовище розробки MS Visual Studio 2005 була обрана мною, тому що створюване програмний засіб орієнтоване на використання в ОС Windows. У ході кодування програми, його тестування і налагодження й навіть проектування були використані різні компоненти середовища: компілятор C + +, складальник об'єктних C + + файлів, відладчик, засоби зворотного проектування, що дозволяють створювати діаграми класів для проекту з вихідного коду його компільованих одиниць, на основі кошти MS Visio 2003.

1.5.2 Мова програмування C + +

C + + - компільований суворо типізований мова програмування загального призначення. Підтримує різні парадигми програмування: процедурну, узагальнену, функціональну; найбільшу увагу приділено підтримці об'єктно-орієнтованого програмування. У 1990-х роках мова стала одним з найбільш широко вживаних мов програмування загального призначення. Більш повну інформацію можна отримати, наприклад, прочитавши книгу творця мови Бйорна Страуструпа [1].

Мова С + + був вибраний мною через його найвищою гнучкості і, звичайно ж, високої опрацьованості парадигми об'єктно-орієнтованого програмування. Із застосуванням саме цієї парадигми здійснено реалізацію програми. Програма повністю побудовано на об'єктах C + + класів (як виняток є кілька використовуваних C-функцій), при цьому широко використовуються концепції успадкування, інкапсуляції і поліморфізму, mutable-члени даних, шаблонні класи та функції. Досить широко застосовуються шаблони контейнерів із стандартної бібліотеки шаблонів (STL), що входить до бібліотеки C + +. У той же час, зважаючи на досить високою опрацьованості використовуються в якості базових для програми бібліотек середовища wxWidgets, відпала необхідність у створенні складних розгалужених структур відносин батько-нащадок (успадкування) на рівні коду розробляється. В основному, успадкування звелося до створення нащадків для досить великого упорядкованого безлічі використовуваних стандартних компонентів wxWidgets.

1.5.3 wxWidgets

wxWidgets являє собою набір бібліотек для створення легко переносите додатків для платформ Win 32, Mac OS X, GTK + та інших (X 11, Motif, WinCE). Він надає в розпорядження розробника єдиний, простий у використанні API. WxWidgets можна використовувати з С + +, Python, Perl, C #. На відміну від деяких інших межплатформенних засобів розробки, wxWidgets дозволяє створювати природно-виглядають на будь-який з перерахованих платформ додатки, так як використовує власні графічні елементи платформи, замість їх емуляції. WxWidgets - добре продуманий, безкоштовний, розширюваний продукт з відкритим вихідним кодом, що робить його вельми корисним при розробці додатків. Більш детальна інформація доступна на офіційному сайті [14], а також в інших джерелах Інтернету.

З огляду на те обставини, що в майбутньому заплановано розширення програми з метою реалізації можливості використання його під Mac OS, для розробки вже першої версії знадобилося використання межплатформенних SDK, таких як wxWidgets або Qt. Перший був обраний через його простоти та доступності.

1.5.4 FreeImage

Безкоштовна бібліотека з відкритим вихідним кодом, FreeImage використовується для роботи з даними зображень. FreeImage надає розробнику зручні засоби для завантаження зображень різних форматів і уніфікує роботу з ними. Це бібліотека з відкритим вихідним кодом, що підтримує роботу з такими популярними сьогодні графічними форматами, як PNG, BMP, JPEG, TIFF і іншими. Для реалізації окремих аспектів (обумовлених у наступних розділах) програми виникла необхідність використання подібного роду засобів. FreeImage була вибрана мною, так як бібліотека досить проста у використанні, швидка, підтримує багатопотокове використання, сумісна з усіма 32-х розрядними версіями Windiws, крім того, підтримує міжплатформову розробку (для Linux і Mac OS X). FreeImage може використовуватися з С, С + +, VB, C #, Delphi, Java, а також у скриптах на Perl, Python, PHP та інших. За більш повною інформацією можна звернутися до офіційного сайту проекту [15].

1.5.5 TinyXML

TinyXML - простий, невеликий, безкоштовний С + + аналізатор XML. TinyXML - одне з багатьох засобів, що використовуються для аналізу XML документів, володіє зручним і компактним зовнішнім інтерфейсом, не вимагає спеціальних знань і тривалого навчання для використання. Використано у реалізації деяких функцій програми для роботи з файловою системою. Офіційний сайт проекту містить додаткову інформацію [16].

1.5.6 Microsoft Office Visio 2003

Microsoft Office Visio 2003 - редактор діаграм і блок - схем для Windows. Використовує векторну графіку для створення діаграм.

Корпорація Visio була створена в 1990 р., і вона досить швидко стала відома на ринку завдяки однойменному програмному продукту. За даними корпорації, в 2000 р. його застосовували близько чотирьох млн. користувачів у 60 країнах світу.

Microsoft Visio 2000, який змінив попередню версію Visio 5.0, - перший продукт, що вийшов під спільною торговою маркою Microsoft і Visio. У технологічному та організаційному плані Visio Corporation стала працювати в складі групи Microsoft за додатками ділового призначення.

Інтерфейс користувача Microsoft Visio 2003 виконано в традиційному стилі продуктів Microsoft Office.

Для побудови діаграм та схем користувач може застосовувати два основних прийоми: малювати вручну і автоматично формувати зображення на основі деяких даних за допомогою широкого набору майстрів.

Наприклад, якщо ви хочете намалювати блок-схему алгоритму, що обчислює факторіал, то слід вибрати в наборі готових шаблонів. Далі потрібно просто перетягувати мишею необхідні графічні об'єкти на малюнок, вставляти в них потрібний текст, з'єднувати об'єкти. При цьому можна встановити режим автоматичного зв'язування об'єктів. Крім набору звичайних властивостей (текст, оформлення, колір та ін) кожному об'єкту може бути приписана одна або кілька гіперпосилань.

Відзначимо також, що крім файлів Visio (. Vsd) можна використовувати досить широкий спектр інших файлів, у тому числі графічних і. Html.

Звичайно, це далеко не всі можливості стандартного пакету Microsoft Visio 2003. Зазначимо тільки, що крім різних діаграм і графіків він дозволяє, наприклад, працювати з найпростішими географічними картами.

Для фахівців інформаційних відділів та розробників ПЗ особливий інтерес представляють функції пакету Microsoft Visio Professional, такі як побудова схем комп'ютерних мереж, діаграм баз даних, структурної схеми програм і карт Web-сайтів. При моделюванні баз даних розробник може формувати опис безпосередньо в середовищі пакету або імпортувати дані з існуючих БД.

Microsoft Visio 2003 становить великий набір засобів для візуального моделювання програм - тут можна використовувати практично всі поширені типи діаграм, якi описуються Unified Modeling Language (UML) версії 1.2. При цьому підтримуються мови програмування C + +, Visual Basic і Java.

Після установки Microsoft Visio 2003 на комп'ютер у засобах розробки, зокрема в Microsoft Visual Studio 2005, автоматично прописуються посилання на пакет. За допомогою команди Reverse Engineer UML Model можна автоматично сформувати опис поточної програми, яке відображається у вигляді ієрархічного дерева у вікні UML Navigator. Треба сказати, що в даному випадку ми отримуємо детальну інформацію про програму (включаючи описи внутрішніх змінних процедури).

Це дуже короткий огляд функцій Microsoft Visio 2003. Для отримання більш повної інформації можна скористатися ресурсами з офіційного джерела [13].

2. Проектування і реалізація завдання

2.1 Вибір формальних моделей

Будь-який проект - це унікальний процес, в ході виконання якого отримують унікальний продукт. Таким чином, для розробки продукту в проекті, швидше за все, повинен застосовуватися унікальний процес. Оптимальним же рішенням при цьому є використання однієї з узагальнених, перевірених на практиці методик, адаптувавши її для конкретного проекту. Як правило, завжди є можливість вибору серед декількох початкових життєвих циклів.

Протягом десятиліть теоретичних досліджень і практичних розробок було розроблено безліч різних моделей життєвих циклів ПЗ. Можна виділити найбільш відомі з них: каскадна модель, V-образна модель, модель швидкого прототипування, модель швидкої розробки додатків (RAD), Інкрементна модель. Кожна з них добре підходить для проектів певного типу, однак застосування її в інших випадках може призвести до невдачі (великих витрат ресурсів), тому до вибору необхідно поставитися дуже уважно.

Для розробки редактора "Easy Particles" за основу моделі життєвого циклу була взята модель швидкого прототипування. На відміну від каскадної моделі, в основі неї лежить не послідовна лінійна структура, а циклова, тому зворотній зв'язок між фазами (з метою виправлення будь-якої проблеми або недоліку, наприклад) не призводить до значного збільшення витрат і збою в графіку. Використання V-подібної моделі не було сенсу, тому що вона застосовується при розробці програмного продукту командою розробників, і особливо орієнтована на верифікацію і атестацію продукту. Відокремленому розробнику було б дуже непросто впоратися з паралельними подіями, що виникають при її використанні. До того ж, як і в каскадної моделі, в ній не враховані ітерації між фазами. Що стосується інкрементний моделі життєвого циклу, вона не могла бути використана, оскільки визначення повної функціональної системи в ній повинно здійснюватися на початку життєвого циклу, а також, оскільки в даній моделі створення одних модулів завершується значно раніше за інших, необхідності в чітко визначених (також у початку життєвого циклу) інтерфейсах. Це неприпустимі умови для розробки редактора, вимоги до функціональності, підтримуваним платформ, призначеному для користувача інтерфейсу були змінені кілька разів у процесі розробки.

Загалом, необхідність застосування структурної еволюційної моделі швидкого прототипування в даному випадку виражена досить явно. Ознаками цього є наступні фактори:

- Повні вимоги не відомі заздалегідь і не постійні;

- Існує потреба у розробці досить складних користувальницьких інтерфейсів;

- Здійснюються тимчасові демонстрації;

- Потрібно зменшити неточності у визначенні вимог; тобто зменшується ризик створення системи, яка не має ніякої цінності для замовника;

- Розробники не впевнені в тому, яку оптимальну архітектуру або алгоритми слід застосовувати;

- Системні інтерфейси ускладнені;

Створення моделі швидкого прототипування було б неможливим без робіт видатного Фреда Брукса ("The Mythical Man - Month", "No Silver Bullet, the Essence and Accidents of Programming"). Його ідеї, викладені в цих книгах, сьогодні настільки ж актуальні, як і в 1975 році. Технології радикально змінили світ, але багато недоліки менеджменту програмних проектів як і раніше ті ж. Десятки років тому Брукс сказав:

"У більшості проектів перша побудована система навряд чи придатна до вживання. Вона може бути дуже повільної, дуже об'ємною, незручною у використанні або володіти всіма трьома переліченими вадами. Немає іншого вибору, крім як почати з самого початку, приклавши всі зусилля, і побудувати модернізовану версію, в якій вирішувалися б усі три проблеми ...

У випадку, коли у проекті використовується нова системна концепція чи нова технологія, розробник змушений побудувати систему, якій згодом не скористається, оскільки навіть при найкращому плануванні неможливо передбачити досягнення потрібного результату ".

Ці слова чудово передають сутність даної моделі, її основну ідею - побудова експериментальних моделей реального програми, іншими словами - Прототипування.

Згідно Джону Коннеллу й Лінди Шафер, еволюційним прискореним прототипом є "дуже піддатлива модифікації та розширення робоча модель передбачуваної системи, не обов'язково представляє собою всі властивості системи, завдяки якій користувачі даного додатки отримують фізичне уявлення про ключові частинах системи до її безпосередньої реалізації; це - легко створювана, без праці піддається модифікації, максимально розширюється, частково задана робоча модель основних аспектів передбачуваної системи ".

Таким чином, прототип - це еквівалент експериментальної моделі або "макета" у світі апаратного забезпечення.

Виконання еволюційних програм при розробці редактора, як і належить, відбувалося в рамках контексту плану, спрямованого на досягнення гранично високої продуктивності. При цьому для замовника був очевидний цей факт, що багато в чому полегшило роботу. Замовник брав активну участь протягом всього процесу розробки, що в цілому є однією з головних умов успішності реалізації методу прототипування.

Схему методу можна зобразити наступним чином:

Малюнок 2.1 - Метод швидкого прототипування

Початок життєвого циклу розробки поміщено в центрі еліпса. У відповідності зі схемою, базовий аналіз (на основі попередніх вимог) необхідних властивостей і функцій редактора був зроблений на початковій стадії розробки (і життєвого циклу в цілому). Замовник і програміст спільно визначили вимоги і специфікації для найважливіших частин системи. У результаті було отримано документ, що описує в загальних рисах приблизні графіки та результативні дані.

Далі було здійснено створення бази даних, користувальницького інтерфейсу, розроблені відповідні функції. Іншими словами, була створена робоча модель - первинний прототип.

Модель була продемонстрована замовнику з метою отримання пропозицій щодо її удосконалення. Замовник оцінив первинний прототип і разом із програмістом визначили проблеми, над усуненням яких необхідно було працювати в рамках розробки подальшого прототипу системи. В основному, зміни торкнулися користувацького графічного інтерфейсу редактора, функціональність ядра системи повністю задовольнила користувача на базі первинного прототипу (за винятком невеликих помилок, виявлених і виправлених згодом).

Всі вищеописані дії являють собою одну ітерацію циклу швидкого прототипування. Цей цикл продовжується до тих пір, поки користувач не буде задоволений тим, яким чином система відображає поставлені до неї вимоги. Команда розробників проекту продовжує виконувати цей процес до тих пір, поки користувач не погодиться, що швидкий прототип в точності відображає системні вимоги.

При розробці поточного проекту було створено два швидких прототипу. Після модифікації другого була отримана остаточна версія системи, офіційно схвалена користувачем. Саме на цьому етапі налаштування прискорений прототип редактора став повністю діючою системою, яка замінила собою часткову систему, отриману в ітераційному циклі прототипування.

Використання даної моделі не раз виправдало себе протягом розробки. У цілому, воно дозволило вирішити наступні проблеми:

- Виходячи з реакції замовників на демонстрації розроблюваного продукту, розробником були отримані відомості про аспекти необхідної поведінки системи, завдяки чому кількість неточностей у вимогах звелося мінімуму;

- Мінімізірованія ймовірності спотворення інформації та виникнення непорозумінь при визначенні системних вимог, що безсумнівно призвело до створення більш якісного кінцевого продукту;

- При розробці утворювалися постійні, видимі ознаки прогресу у виконанні проекту, завдяки чому замовники відчували себе впевнено;

- Завдяки меншому об'єму доробок були зменшені витрати на розробку;

- Завдяки тому, що проблеми, як правило, виявлялися до залучення додаткових ресурсів, скоротилися загальні витрати;

- Було забезпечено управління ризиками;

2.2 Структурна модель застосунку

Програма складається з двох основних сутностей:

а) чергу емітерів;

б) віконно-інтерфейсна частина;

Сутності, у свою чергу складаються з безлічі функціонально-логічних блоків.

Черга емітерів являє собою програмований контейнер для зберігання параметрів набору емітерів та їх часток, а також відображення в режимі реального часу. Черга також визначає режими змішування та порядок малювання наборів часток один щодо одного. Це дозволяє створювати різні ефекти накладення.

Окремо взятий набір часток представлений внутрішніми структурами даних емітера. Тут зберігаються всі параметри емітера і кожної його частинки:

а) для емітера:

1) координати у двовимірній декартовій системі;

2) швидкість;

3) розміри;

4) значення розкиду часток;

5) стартова затримка і тривалість генерації;

б) для частинки:

1) текстура;

2) час життя;

3) швидкість по осях;

4) гравітація по осях;

5) значення початкових і кінцевих розтягувань;

6) значення початкового та кінцевого квітів по каналах;

Для реалізації інтерфейсної частини були використані графічні об'єкти вищеописаного міжплатформного движка wxWidgets.

Кореневим елементом інтерфейсної частини є основною фрейм. Основний фрейм служить для розташування фрейму введення даних, фрейму управління чергою емітерів, фрейму виводу. Також основним фрейму належать системне меню, панелі інструментів і статусу.

Фрейм введення даних призначений для введення вищезазначених параметрів поточного емітера. У редакторі завжди є поточний емітер, якщо їх кількість більша нуля. Якщо ж воно дорівнює нулю, інструменти фрейму введення блокуються. При зміні поточного емітера відбувається відповідне оновлення даних інструментів фрейму введення.

Фрейм управління чергою емітерів являє собою панель із схематичним відображенням окремих емітерів у вигляді піктограм. До функцій фрейму належать додавання та видалення емітерів, копіювання емітера з усіма його параметрами, зміна поточного емітера, а також порядку промальовування емітерів. Для копіювання і видалення емітерів при активному фреймі управління чергою можна використовувати гарячі клавіші (Ctrl + V, Ctrl + X, відповідно).

Фрейм виведення об'єднує в собі всю функціональність виведення графічних даних програми. Для максимально швидкого виведення використовується низькорівнева робота з апаратним забезпеченням відеосистеми, що здійснюється за допомогою драйвера OpenGL. Доступ до переносних незалежного конвеєру OpenGL здійснюється, у свою чергу, через інтерфейс wxWidgets. Саме на рівні фрейму висновки здійснені зв'язування віконної системи і функціональності малювання черги емітерів, що не залежить від конкретного вікна і працює з буферами OpenGL. Засоби wxWidgets використовують для цього ті чи інші системні бібліотеки, в залежності від цільової платформи. Для Windows це WGL, для Mac OS X - AGL, а також стандартні Carbon (для С + +) і Cocoa (Objective С).

Додатково фрейм висновку дозволяє за допомогою миші переміщувати емітери, змінювати їх розміри. Також підтримується перенесення робочого (поточної відображається) області малювання. Для цього необхідно, по-перше, активувати режим перенесення, використавши клавішу Space. Потім, використовуючи мишу, здійснити перенесення області в потрібному напрямку і на необхідну відстань. Для виходу з режиму переносу робочої області необхідно повторно натиснути клавішу Space. Необхідно відзначити, що в режимі переносу робочої області можливості перенесення емітерів та зміни їх розмірів відключаються.

Системне меню має наступну структуру:

- Меню "Файл", що відповідає за загальний скидання, збереження і завантаження, вихід з програми;

- Меню "Черга", що відповідає за установку режиму відображення емітерів (Playback, Loop playback, Static), додавання і видалення поточного емітера, копіювання емітера і набору його параметрів, скидання всіх емітерів;

- Меню "Інформація", що дозволяє отримати інформацію про способи використання редактора, а також про розробника;

Панель інструментів містить наступні компоненти:

а) функції установки режиму відображення емітерів:

1) Playback;

2) Loop playback;

2) Static;

б) функції збереження і завантаження:

1) Save;

2) Load;

в) функції настройки відображення:

1) Back color;

2) Back image;

3) режим змішування;

Панель статусу має два поля: кількість відображених за секунду, число часток, число примітивів, швидка підказка (про ситуацію).

Отримати інформацію про внутрішню структуру програми можна, звернувшись до діаграми класів (Додаток Г).

2.3 Функціональна модель застосунку

Розроблений редактор має шість базових функціональних блоків: налаштування черги емітерів, оновлення, відображення, введення / висновок, налаштувати і робота з довідковою системою програми (у базовій версії зводиться до отримання загальної інформації про функціональність редактора і розробника, згодом планується розширення).

Налаштування черги емітерів, у свою чергу, складається з набору на функцій з управління чергою (додавання емітерів, видалення емітерів, копіювання емітерів з перенесенням їх параметрів) і набору функцій по установці параметрів поточного емітера і його частинок.

Функція відображення реалізує виведення на екран створюваних ефектів.

Функції введення і виводу дозволяють користувачеві зберігати поточний проект, а саме - дані про емітера і про додаткові параметри відображення, на зовнішній носій, і завантажувати проекти, які були збережені раніше.

Функції налаштування відображення полягають у встановленні додаткових параметрів відображення (перерахованих у попередньому підрозділі).

Отримати більш детальну інформацію про безліч і структурі інтерфейсних функцій програми можна, звернувшись до діаграми варіантів використання (Додаток Д). На ній відображена декомпозиція найбільших інтерфейсних блоків. Діаграма дозволяє в наочній формі представити набір дій, здійснюваних користувачем, якими визначається робота редактора.

2.4 Інформаційна модель застосунку

Інформаційна модель застосунку відображає потоки інформації, що проходять між його модулями і зовнішніми сутностями.

Розроблюваний редактор частинок є однокористувацький додатком, тому що підтримує інтерфейс одночасно лише з одним користувачем. Таким чином, першою зовнішньої сутністю є користувач.

Дані про частки, оброблені редактором, виводяться на зовнішній носій у вигляді текстових файлів формату XML. Пізніше ці файли можуть бути використані як редактором, так і поставляється разом з ним інструментарієм у контексті цільового додатки. Таким чином, другий зовнішньої сутністю є носій даних.

За безпосередній прийом даних емітерів від користувача відповідає інструментарій фрейму введення. Бібліотеки операційної системи надають для цього все необхідне, а використання предкомпіляторних "фільтрів" wxWidgets дозволяє і зовсім забути про платформу.

Після введення дані направляються в першу основну сутність програми - черга емітерів. Там вони зберігаються, використовуючись при виведенні (деякі поля модифікуються при цьому).

У свою чергу, введення керуючих сигналів здійснюється через аналогічні інструменти панелі інструментів. Ці дані містяться в службові поля черги емітерів, а також фрейму виводу.

Обмін даними з зовнішніми носіями здійснюється за відповідними керуючим командам. При збереженні здійснюється з'їм даних черги емітерів, параметрів відображення, що зберігаються в фреймі виведення, іншої службової інформації, що характеризує стан програми, які форматуються встановленим чином (використовується інструмент TinyXML) і виводяться. При завантаженні відбувається прямо протилежна послідовність дій.

Узагальнюючи вищесказане, до основних потоків даних програми можна віднести:

а) введення користувачем у систему параметрів емітерів:

1) координати у двовимірній декартовій системі;

2) швидкість;

3) розміри емітера;

4) значення розкиду часток;

5) стартова затримка і тривалість генерації;

б) введення користувачем у систему параметрів частинок емітера:

1) текстура;

2) час життя;

3) швидкість по осях;

4) гравітація по осях;

5) значення початкових і кінцевих розтягувань;

6) значення початкового та кінцевого квітів (32 bit), по каналах;

в) висновок графічної інформації системи емітерів в буфер зображення;

Графічно інформаційна модель застосунку представлена ​​в Додатку В, на діаграмі потоків даних.

2.5 Об'єктна модель застосунку

Оскільки додаток було розроблено з використанням можливостей об'єктно-орієнтованої мови С + +, слід розкрити його об'єктну структуру. Докладно об'єктна структура програмного засобу описана в Додатку Г, тут же можна привести загальний огляд системи класів.

а) клас MyApp, відповідає за ініціалізацію програми, створюється і управляється повністю з середовища wxWidgets. Це кореневої клас всій проектованої частини програми.

б) модуль черги емітерів. Включає в себе:

1) клас ParticleSystemChain, тобто безпосередньо саму чергу; в системі існує singleton-об'єкт даного класу;

2) містяться в черзі емітери - об'єкти класу ParticleSystem;

3) для формування і використання коректних OpenGL текстур на підставі бітових зображень використовуються об'єкти класу MyTexture.

в) клас MainFrame - кореневої клас віконного користувальницького інтерфейсу; в системі існує singleton-об'єкт даного класу;

г) клас PSChainFrame являє собою вікно управління чергою систем;

д) об'єкти PSLabel застосовуються в PSChainFrame для подання емітерів, представляють собою піктограми;

е) PSInputFrame використовується для введення призначених для користувача даних активної системи;

ж) об'єкти класів MySpinCtrld і MySpinEditCtrld - призначені для користувача елементи управління, що використовуються для введення чисел з плаваючою точкою з зазначеного діапазону, застосовуються в PSInputFrame;

з) PSOutputFrame використовується для відображення результатів роботи програми (виведення обчислених графічних примітивів - частинок); об'єкт MyCanvas - надається OpenGL в якості контексту візуалізації;

Це загальний перелік розроблених в рамках програмного засобу класів з коротким описом їх функціональності. Взаємозв'язки між ними та іншими, менш значними, класами, а також внутрішня структура класів в більш повному вигляді розкривається в Додатку Г.

2.6 Вимоги до програмних, апаратних ресурсів і ОС

Для складання застосування необхідна наявність набору вбудованих (статичних) бібліотек середовища wxWidgets, встановлених в системний каталог (або в один з каталогів пошуку статичних бібліотек, зазначених у налаштуваннях середовища розробки Microsoft Visual Studio 2005 і у властивостях проекту). Для коректної роботи програми необхідна наявність у системі динамічної бібліотеки OpenGL (будь-якої версії, за умовчанням з OS Windows поставляється версія 1.0). Драйвер OpenGL використовується для растеризації графічних даних, що генеруються редактором.

Додаток вимагає не більше 30 MB оперативної пам'яті, 20 MB - віртуальної, 40 MB дискового простору.

Мінімальна дозволу дисплея монітора, необхідну для коректної роботи програми, становить 1024 x 768 точок.

Програма працює під управлінням будь-O З Windows (версії не нижче Windows XP SP 2).

Крім того, для коректної роботи програми, зібраного в Microsoft Visual Studio 2005, необхідна наявність у системі встановлених спеціальним чином бібліотек (так званих маніфестів), інакше програма не запуститься. В якості альтернативи можна зібрати додаток з використанням Microsoft Visual Studio 2003, однак при цьому буде використаний графічний користувальницький інтерфейс старого зразка.

3. Тестування

3.1 Аналіз надійності

Випробування проводяться з метою виявлення відхилень у роботі програми та результати її функціонування, оцінки причин таких відхилень. Відхилення отриманих результатів від еталонів використовуються для оцінки якості програми.

Основним методом виявлення помилок при проведенні випробувань програми було тестування, в якому доцільно виділити три стадії:

- Тестування для виявлення помилок в програмі, де виявлялися всі відхилення результатів функціонування реальної програми від заданих еталонних значень;

- Тестування для діагностики виявлених спотворень результатів, з метою виявлення інструкцій і даних, які стали причиною відхилення результатів від еталонних при тестуванні для виявлення помилок;

- Тестування для контролю виконаних коригувань програми і даних, де підтверджувалася правильність виконаної коригування.

Говорячи про тестування, розуміється перевірка програми не тільки в статичному режимі, коли виявляються помилки коду програми, а й динамічна перевірка, що включає контроль адекватності реакції системи на заявки користувача і поведінки системи при виникненні неприпустимих ситуацій.

Знайдені помилки усувалися, процес продовжувався до тих пір, поки робота програми не була визнана задовільною.

3.2 Тестові приклади

Під час тестування було проведено ряд тестів різної спрямованості:

- Тест коректності вводяться для користувача даних, в рамках якого була перевірена система введення всіх видів даних, використовуваних додатком, зі спробами введення некоректних даних;

- Тест працездатності з граничними значеннями параметрів; будь-який додаток необхідно перевіряти на працездатність в граничних станах, так як, в силу своєї неочевидності і низькій вірогідності виникнення, це, як правило, найбільш вузькі місця у функціональності;

- Тест коректності роботи програми на ПК з різними конфігураціями (драйверами графічного прискорювача); додатки, що використовують низькорівневий функціональність драйвера (або близьку до неї), необхідно додатково тестувати на сумісність з різними різновидами драйверів даного типу. У випадку з розробляємо додатком, необхідно виконати перевірку на коректність його роботи з різними драйверами відеосистеми, оскільки додаток використовує низькорівневі можливості OpenGL в якості своєї осьової функціональності.

3.3 Реакція програми на тести

За допомогою вбудованого компілятора були виявлені синтаксичні помилки. Варто відзначити, що допущення безлічі тривіальних синтаксичних помилок є нормальним явищем при розробці програмного засобу, тому рекомендується як можна частіше виконувати рекомпіляції поточного розроблюваного програмного модуля. Це дозволяє виявляти такі помилки і уникати їх накопичення. В іншому випадку відбувається сильне ускладнення процесу їх локалізації у фінальній версії модуля, так як вони починають впливати один на одного. У такій ситуації буває важко відокремити одну помилку від іншої.

Після успішної компіляції і збірки додатку, безпосередньо в процесі тестування, були виявлені і усунені помилки часу виконання. З найбільш важко-усунених можна відзначити помилку приведення даних типів з плаваючою комою при користувача введенні (що призводило до їх неявному перекручуванню), а також помилки проектування користувальницького інтерфейсу, у зв'язку з чим останній був цілком перероблений кілька разів. Під час тестування програми з графічним прискорювачем від фірми ATI були виявлені помилки ініціалізації текстурних даних, через що порушувався їх висновок. З помилок роботи програми при встановлених граничних значеннях параметрів можна виділити помилку генерації часток при заданій ширині та / або висоті емітера, що дорівнює нулю. При цьому для частинок генерувалися координати, сильно виходять за межі кордонів емітера. Цю помилку можна назвати логічною помилкою програми.

При усуненні знайдених помилок налагодження програми здійснювалася вбудованим відладчиком MS Visual Studio 2005.

3.4 Висновок за результатами тестування

Мета проведення випробувань полягала в тому, щоб розглянути всі можливі варіанти роботи програми, протестувати її в нормальних, виняткових та екстремальних умовах, виявити недоліки і усунути їх, якщо такі мали місце.

У результаті випробувань на контрольних прикладах було доведено, що дана програма працює згідно із заданим алгоритмом. Всі помилкові ситуації були розглянуті, помилки - усунені.

4. Застосування програми

4.1 Призначення програми

Програма призначена для створення і редагування складних графічних ефектів частинок. У процесі розробки була забезпечена реалізація програмою наступного набору функцій:

- Управління динамічним набором емітерів (систем частинок);

- Управління частками кожного емітера;

- Управління загальними параметрами малювання;

- Введення і виведення даних на зовнішні носії;

4.2 Інсталяція програми

Розроблене програмне засіб не потребує інсталяції. Однак слід зауважити, що для роботи програми необхідна наявність у системі динамічної бібліотеки OpenGL будь-якої версії (з MS Windows за замовчуванням поставляється версія 1.0).

Крім того, для коректної роботи програми, зібраного в Microsoft Visual Studio 2005, необхідна наявність у системі встановлених спеціальним чином бібліотек (так званих маніфестів), інакше програма не запуститься. В якості альтернативи можна зібрати додаток з використанням Microsoft Visual Studio 2003, однак при цьому буде використаний графічний користувальницький інтерфейс старого зразка. Більш докладно про маніфестах, їх типи і призначення, можна прочитати на офіційному сайті корпорації Microsoft [13].

4.3 Структура вхідних даних

Вхідними даними додатка служать параметри емітерів, що задаються користувачем, а також параметри відображення. Більш докладно зі структурою вхідних даних можна ознайомитися в підрозділі 1.1, або на діаграмі потоків даних (Додаток В).

4.4 Діалог з користувачем

Діалог з користувачем здійснюється за допомогою панелі стану, що розташовується внизу екрану програми. На ній здійснюється виведення поточної частоти оновлення картинки, а також контекстні підказки, вміст яких залежить від поточних дій користувача.

При спробі виходу з програми з незбережених даними проекту здійснюється запит користувача про необхідність виконати збереження даних.

При запиті довідкової інформації системи допомоги або інформації про розробника здійснюється активація діалогових вікон з відповідними запитом даними.

В іншому, з урахуванням типу й призначення програми, використовуваного в ньому інтуїтивно зрозумілого, продуманого графічного інтерфейсу, необхідність у додатковій зворотного зв'язку з користувачем відпадає.

4.5 Форма представлення вихідних даних

Вихідні дані формуються, як вже було зазначено вище, в декількох формах. Можна переглядати вихідну інформацію в графічному вигляді безпосередньо на екрані редактора. Також розробник програми, що використовує редактор (надається розробнику вихідний код для виведення ефектів часток), може виводити дані у вікно свого застосування (попередньо зв'язавши його з OpenGL засобами ОС). Нарешті, можна переглядати вивантажені на диск вихідні дані за допомогою будь-якого текстового (XML) редактора.

5. Оптимізація зорового взаємодії оператора з засобами відображення інформації па основі ЕЛТ

5.1 Особливості зорового сприйняття інформації та формування втоми зорового аналізатора оператора

Зорове сприйняття - сукупність процесів побудови зорового образу навколишнього світу. З цих процесів більш прості забезпечують сприйняття кольору, яке може зводитися до оцінки світлини, або видимої яскравості, колірного тону, чи власне кольору, і насиченості як показника відмінності кольору від сірого рівної з ним світлини. При цьому основні механізми колірного сприйняття мають вроджений характер і реалізуються за рахунок структур, локалізованих на рівні підкіркових утворень мозку. Більш філогенетично пізніми є механізми глядацького сприйняття простору, в яких відбувається інтеграція відповідної інформації про простір, отриманої також від слуховий, вестибулярної, шкірно-м'язової сенсорних систем. У просторовому зір виділяють два основні класи перцептивних операцій, які забезпечують константне сприйняття. Одні дозволяють оцінювати віддаленість предметів на основі бінокулярного та монокулярного паралакса руху. Інші дозволяють оцінити напрям. В основному просторове сприйняття забезпечується вродженими операції, але їх остаточне оформлення відбувається в купованому протягом життя досвіді практичних дій з предметами. Просторове сприйняття є основою сприйняття руху, яке також здійснюється за рахунок вроджених механізмів, що забезпечують детекцию руху. Більш складними операціями зорового сприйняття є операції сприйняття форми, які і в філогенезі, і онтогенезі формуються досить пізно. Основою виступає сприйняття просторових угруповань як об'єднання однотипних елементів, розташованих у досить вузькому зоровому полі.

У процесі роботи на комп'ютері, навіть відповідає всім вимогам ТСО, при дотриманні ергономічних параметрів робочого місця і правильної організації режимів праці та відпочинку користувач все-таки може відчувати певну зорову і м'язову втому, фізичний і психологічний дискомфорт, які посилюються, якщо не вжити профілактичних заходів . При використанні вже застарілих на сьогоднішній день (у відношенні дисплеїв ПК) ЕПТ, цей ефект проявляється особливо сильно, тому що навантаження на органи зору в цьому випадку набагато вище. При цьому знання та здійснення профілактичних заходів стає абсолютно необхідною умовою тривалої та безпечної для здоров'я роботи з дисплеєм.

До профілактичних заходів належать комплекси вправ для очей, для зняття загального і локального втоми з різних груп м'язів організму, для стимуляції діяльності нервової, серцево-судинної, дихальної систем, для підвищення рухової активності та розумової працездатності.

Найбільш поширеним нездужанням у користувачів ПК є зорове стомлення, яке за відсутності належних заходів і при продовженні роботи може проявитися у вигляді частого моргання, свербіння і печіння в очах, різі, сльозотечі і інших реакцій.

У якості профілактичних заходів для зниження втоми очей, поліпшення кровопостачання очного яблука, релаксації окорухових м'язів рекомендується проводити спеціальні вправи для очей, дорослим користувачам - під час регламентованих перерв разом з іншими комплексами фізичних вправ, а студентам - через кожні 20-25 хвилин роботи. При появі зорового дискомфорту ці вправи слід проводити індивідуально, самостійно і раніше зазначеного часу.

Фахівцями-медиками і гігієністами розроблено велику кількість різноманітних вправ, спрямованих на відновлення і захист від перевантажень органів зору вправ. Вони широко представлені, наприклад, в джерелі [8].

Наведемо приклад одного з найбільш простих у реалізації вправ. Вправа називається "пальмінг" і полягає в наступному. Пальці рук, складені разом, слід перехрестити в центрі лоба. При цьому долоні накриють очні западини, повністю виключаючи доступ світла, і в той же час не будуть стискати очні яблука, залишаючи можливість вільно рухати століттями. У процесі такого відпочинку органів зору, тобто в період припинення до них доступу світла, відбуваються хімічне відновлення рецепторів очей і розслаблення м'язових волокон, які перенесли напругу після інтенсивних потоків образів. Подібне штучне затемнення зору є одним з кращих вправ для очей, значно прискорюючи процес розслаблення очних м'язів і покращуючи кровообіг. Двохвилинний пальмінг відновлює функціональні властивості сітківки ока.

Зрозуміло, перед можливою систематичною роботою з дисплеями для гігієни зору і його профілактичного контролю необхідно попередньо пройти всебічне обстеження в окуліста і надалі регулярно, не менше одного разу на рік, повторювати це обстеження.

При виникненні помітного зорового дискомфорту в процесі роботи, незважаючи на гарну якість монітора, правильну ергономічну організацію праці та дотримання режимних вимог, а також виконання зазначених вправ, слід обмежити час роботи з дисплеєм. У цьому випадку повинна бути або збільшена тривалість перерви для відпочинку, або проведена зміна діяльності.

5.2 Інженерно-психологічні вимоги до засобів відображення інформації (СОІ) та їх розташування в робочому просторі

Засоби відображення інформації призначені для отримання людиною відомостей про стан об'єкта управління, хід виробничого процесу, наявності енергетичних ресурсів, стан каналів зв'язку і т. д. Ці дані пред'являються людині у вигляді кількісних та якісних характеристик. Засоби відображення інформації можуть застосовуватися, наприклад, у тих випадках, коли людина не може безпосередньо спостерігати за технологічним процесом внаслідок його територіальної віддаленості, шкідливості або небезпеки при контакті з предметом праці.

Засоби відображення інформації сприяють підвищенню точності безпосереднього спостереження, з їх допомогою інформація пред'являється в більш зручній для сприйняття і обробки формі. Широке впровадження систем дистанційного управління призвело до того, що іноді СОІ стають єдиним джерелом інформації про керований об'єкт і робочому процесі. У цьому випадку людина має справу не з реальними об'єктами, а з їх моделями, тобто з інформацією, організованою відповідно до певною системою правил і подається на засоби її відображення. Інформаційна модель дозволяє людині аналізувати стан керованого об'єкта, приймати рішення і здійснювати контроль і управління процесом виробництва.

Ергономічні вимоги до візуальних СОІ встановлюють необхідні виробничі, яскравості, частотні характеристики зорових образів, а також способи їх розміщення на робочому місці. Порушення цих вимог призводить до зниження ефективності робочого процесу, підвищенню рівня небезпеки для здоров'я та життя працівників та іншим негативним результатами.

Всі ергономічні вимоги викладені у відповідних ГОСТах (ГОСТ 21829 - 76, ГОСТ 21480-76, ГОСТ 21837-76, ГОСТ 22902-78).

Зупинимося на основних вимогах до моніторів і характеристиках зображення на екрані.

Монітор - це, як правило, єдиний пристрій, "обличчям до обличчя" з яким користувач проводить не один рік. Удобочитаемость інформації на екрані залежить від чіткості елементів зображення. Основними параметрами зображення на екрані монітора є яскравість, контраст, розміри і форма знаків, відбивна здатність екрану, наявність або відсутність мерехтінь.

Основні нормовані візуальні характеристики моніторів і відповідні допустимі значення цих характеристик наведено у таблиці 5.1.

Таблиця 5.1 - Деякі нормовані візуальні параметри моніторів [9]

Параметри

Допустимі значення

Яскравість знака або тла (вимірюється в темряві)

35-120 кд/м2

Контраст

Від 3:1 до 1,5:1

Тимчасова нестабільність зображення (мерехтіння)

Не повинна бути зафіксована более90% спостерігачів

Кутовий розмір знака

16-60

Відношення ширини знака до висоти

0,5-1,0

Відбивна здатність екрану (відблиски)

не більше 1%

Нерівномірність яскравості елементів знаків

не більше (25%)

Нерівномірність яскравості робочого поля екрану

не більше (20%)

Формат матриці знаку

не менше 7 * 9 елементів зображення

Розмір мінімального елемента відображення (пікселя) для монохромного монітора, мм.

0,3

Допустиме вертикальне зміщення однотипних знаків,% від висоти матриці

не більше 5

Допустима просторова нестабільність зображення (тремтіння по амплітуді зображення) при частоті коливань в діапазоні від 0,5 до 30 Гц, мм

не більше 2L * 10 -4 (L-відстань спостереження, мм.)

Крім того, комп'ютери та монітори, а також організація робочих місць операторів повинні відповідати прийнятим на території Республіки Білорусь санітарним правилам і нормам [7], що стосуються охорони зору користувачів персональних комп'ютерів:

Конструкція монітора повинна забезпечувати можливість фронтального спостереження екрана шляхом повороту корпуса в горизонтальній площині навколо вертикальної осі в межах 30 ° і у вертикальній площині навколо горизонтальної осі в межах 30 ° з фіксацією в заданому положенні. Дизайн монітора повинен передбачати фарбування корпусу в спокійні м'які тони з дифузійним розсіюванням світла.

Корпус монітора і ПК, клавіатура та інші блоки і пристрої для ПК повинні мати матову поверхню одного кольору і не мати блискучих деталей, здатних створювати відблиски. На лицьовій стороні корпусу монітора не рекомендується розташовувати органи управління, маркування, будь-які допоміжні написи і позначення. При необхідності розташування органів управління на лицьовій панелі вони повинні закриватися кришкою або бути втоплені в корпусі.

Екран відеомонітора повинен знаходитися від очей користувача на оптимальній відстані 600-700 мм, але не ближче 500 мм з урахуванням розмірів алфавітно-цифрових знаків і символів.

Робоче місце з монітором і ПК має бути оснащене легко переміщується пюпітром для документів.

Рівень очей при вертикально розташованому екрані монітора має припадати на центр або 2 / 3 висоти екрана. Лінія погляду повинна бути перпендикулярна центру екрану і оптимальне її відхилення від перпендикуляра, що проходить через центр екрана у вертикальній площині, не повинен перевищувати 5 °, дозволене - 10 °.

5.3 Вимоги до організації, якісним і кількісним характеристикам освітлення робочого місця оператора і їх реалізація. Оптимізація режиму праці та відпочинку оператора

Раціональне освітлення приміщень - один з найбільш важливих факторів, від яких залежить ефективність трудової діяльності людини.

Гарне освітлення необхідно для виконання більшості завдань оператора. Для того щоб спланувати раціональну систему освітлення, враховується специфіка робочого завдання, для якого створюється система освітлення, швидкість і точність, з якою це робоче завдання має виконуватися, тривалість його виконання й різні зміни в умовах виконання робочих операцій.

Нормами для даних робіт встановлено необхідну освітленість робочого місця Ен = 300лк (середня точність роботи по розрізненню деталей розміром від 1 до 10 мм).

Для освітлення робочого місця оператора звичайно використовуються люмінесцентні лампи - вони мають ряд переваг перед лампами розжарювання: їх спектр ближче до природного, вони мають велику економічність (більше світловіддача) і термін служби (у 10-12 разів). Поряд з цим є і недоліки: їх робота іноді супроводжується шумом, вони гірше працюють при низьких температурах, мають малу інерційність.

Загалом, всі основні вимоги до освітлення приміщень установ застосовуються також до висвітлення робочих місць у відеоекранів дисплейних пристроїв. Однак є цілий ряд особливостей роботи у відеоекранів, які необхідно враховувати. Крім ретельного обмеження відображення це пов'язується, перш за все, з правильним вибором рівня освітленості і проблем зменшення стрибків яскравості при зміні поля зору. Джерела світла, такі як світильники і вікна, які дають віддзеркалення від поверхні екрану, значно погіршують точність знаків. Найбільш важливим є співвідношення яскравостей при нормальних умовах роботи, тобто освітленість на робочому місці близько 300 лк, і середня щільність заповнення відеоекрани. Відображення, як на екрані, так і на робочому столі і клавіатурі, тягне за собою перешкоди фізіологічного характеру, які можуть виразитися в значній напрузі, особливо при тривалій роботі. Відображення, в тому числі і від вторинних джерел світла, повинне бути зведено до мінімуму. Для захисту від надмірної яскравості вікон можуть бути застосовані завіси, штори і екрани. Використання додаткового освітлення робочого столу, наприклад, для освітлення документів з нечітким шрифтом, збільшує співвідношення яркостей між документацією і екраном і є небажаним без відповідного регулювання яскравості екрану.

У приміщенні, призначеному для роботи на комп'ютері, має бути як природне, так і штучне освітлення.

Що стосується природного освітлення, краще всього, якщо вікна в кімнаті виходять на північ або північний схід. Як вже було сказано, в поле зору користувача не повинно бути різких перепадів яскравості, тому вікна бажано закривати шторами або жалюзі. Рівень природного освітлення нормується коефіцієнтом природної освітленості (КПО) - це відношення природної освітленості всередині приміщення Евн до одночасного значення зовнішньої горизонтальної освітленості Ен. Освітленість Е вимірюється в люксах (Лк). Фактична освітленість повинна бути більше або дорівнює нормованої. При експлуатації будинків необхідно підтримувати світловіддачу і светопропускаемость вікон, тобто виробляти їх своєчасну чистку. При незначному виділення пилу - 4 рази на рік.

Штучне освітлення може бути загальним і комбінованим, внутрішнім і зовнішнім. Штучне освітлення забезпечується електролампами різної потужності, укладеними в спеціальну арматуру (світильники, різних типів і виконань).

Штучне освітлення робочого місця оператора має бути загальним і рівномірним, використання одних тільки настільних ламп неприпустимо.

Одним з головних способів вплинути на процеси втоми оператора є встановлення відповідних режимів праці.

При розподілі робіт протягом тижня слід враховувати, що працездатність збільшується в перші дні тижня, досягає найвищого рівня на третій-четвертий день, а потім знижується.

Розподіл робіт протягом зміни має враховувати, що період вироблення в операторів ПК складає від 10 до 40 хвилин (у післяобідній час період вироблення скорочується). Період стійкої працездатності триває близько двох годин; період настання стомлення і спаду працездатності настає після 1,5-2,0 годин стійкої працездатності (у другій половині робочого дня період втоми більш виражений).

Режими праці та відпочинку при роботі з ПК протягом зміни повинні організовуватися в залежності від виду та категорії трудової діяльності.

Види трудової діяльності поділяються на 3 групи:

а) група А - робота з зчитування інформації з екрана ПК з попереднім запитом;

б) група Б - робота з введення інформації;

в) група В - творча робота в режимі діалогу.

При виконанні протягом робочої зміни робіт, що відносяться до різних видів трудової діяльності, за основну роботу з ПК слід приймати таку, яка займає не менше 50% часу протягом робочої зміни або робочого дня.

Для видів трудової діяльності встановлюється 3 категорії тяжкості і напруженості роботи з ПК, які визначаються:

а) для групи А - по сумарному числу прочитуються знаків за робочу зміну, але не більше 60 000 знаків за зміну;

б) для групи Б - по сумарному числу зчитуються або вводяться знаків за робочу зміну, але не більше 40 000 знаків за зміну;

в) для групи В - по сумарно часу безпосередньої роботи з ПК за робочу зміну, але не більше 6 годин за зміну.

Кількість перерв на відпочинок у принципі, має відповідати кількості виражених фізіологічних спадів функціонування тим організму, що виникають при стомленні під час трудового процесу. Краще всього підійти до цього питання суто індивідуально і провести відповідні дослідження. А в загальному випадку час регламентованих перерв протягом робочої зміни встановлюється в залежності від її тривалості, виду і категорії трудової діяльності (таблиця 5.2).

Таблиця 5.2 - Час регламентованих перерв у залежності від тривалості робочої зміни, виду і категорії трудової діяльності з ПК

Категорія роботи з ПК

Рівень навантаження за робочу зміну при видах робіт з ПК

Сумарний час регламентованих перерв, хв.


група А, к-ть знаків

група Б, к-ть знаків

група В, годину.

при 8-годинній зміні

при 12-годинній зміні

I

до 20000

до 15000

до 2,0

30

70

II

до 40000

до 30000

до 4,0

50

90

III

до 60000

до 40000

до 6,0

70

120

Час перерв дано при дотриманні оптимальних режимів праці, у противному випадку час регламентованих перерв слід збільшити на 30%.

При роботі з графічними елементами менше 0,5 мм, тривалість зосередженого спостереження повинна бути не більше 50% часу зміни.

Тривалість безперервної роботи з ПК без регламентованого перерви не повинна перевищувати 2 годин.

При багатозмінної роботі, що актуально для диспетчерів, та й взаємини з Internet часто змушують до такого режиму, фізіологічно раціональне час початку та закінчення роботи зміни знаходиться в наступних інтервалах: 6 - 8 годин, 14 - 16 годин, 0 - 4 години.

При роботі з ПК в нічну зміну (з 22 до 6 годин), незалежно від категорії і виду трудової діяльності, тривалість регламентованих перерв повинна збільшуватися на 60 хвилин. При 8-годинній робочій зміні і роботі на ПК регламентовані перерви слід встановлювати:

а) I категорія робіт - через 2 години від початку робочої зміни і через 2 години після обідньої перерви тривалістю 15 хвилин кожний;

б) II категорія робіт - через 2 години від початку робочої зміни і через 1,5 - 2 години після обідньої перерви тривалістю 15 хвилин кожен або тривалістю 10 хвилин через кожну годину роботи;

в) III категорія робіт - через 1,5 - 2 години від початку робочої зміни і через 1,5 - 2 години після обідньої перерви тривалістю 20 хвилин кожен або тривалість 15 хвилин через кожну годину роботи.

При 12-годинній робочій зміні регламентовані перерви повинні встановлюватися в перші 8 годин роботи аналогічно перервам при 8-годинний робочій зміні, а протягом останніх 4 годин роботи, незалежно від категорії і виду робіт, кожну годину тривалістю 15 хвилин.

При недотриманні прийнятих санітарних норм СанПиН 9-131 РБ 2000, а також вимог, яких необхідно дотримуватися, щоб уникнути помилок, які може допустити в процесі роботи оператор, призводить до психофізіологічних перевантажень оператора.

6. Обгрунтування економічної доцільності розробки ПС "Easy Particles"

6.1 Загальна характеристика розробляється ПС ВТ

Особливістю сучасних бізнес-процесів в будь-якій галузі суспільної діяльності є автоматизація збору і обробки інформації для прийняття управлінських рішень. Разом з тим, автоматизація неможлива без використання програмних продуктів. Рішення будь-якої інформаційної завдання пов'язане із застосуванням не тільки системних програм, але й різноманітних програмних засобів - додатків.

Розробка проектів програмних засобів потребує витрат різноманітних і, не рідко значних обсягів, ресурсів (трудових, матеріальних, фінансових). У зв'язку з цим, розробка і реалізація кожного проекту повинна бути обгрунтована, як технічно, так і економічно.

Проект варто розробляти, якщо він дає певні переваги в порівнянні з відомими передовими аналогами або, в крайньому разі, в порівнянні з існуючою практикою. Тому, до того як приступити до розробки проекту програмного засобу, фахівець повинен, використовую відповідні методи, знайти найбільш раціональне програмне рішення, що забезпечує високий технічний рівень програми і дає суттєву економію ресурсів, як при розробці проекту в науково-технічної організації (у розробника), так і при його реалізації у користувача (покупця, замовника).

Програмний засіб функціонального призначення "Easy Particles" - графічний редактор, розроблений на C + + з використанням MS Visual Studio 2005 і ряду спеціалізованих бібліотек, є ПС 1 групи складності.

Розроблюване програмний засіб належить до 1-ї групи складності. За ступенем новизни програмний продукт відноситься до групи "В" з коефіцієнтом 0,7.

6.2 Розрахунок ціни і прибутку на ПС

У сучасних ринкових економічних умовах ПС виступає переважно у вигляді продукції організацій, що представляє собою функціонально завершені і мають товарний вигляд ПС ВТ, реалізовані покупцям за ринковими відпускними цінами. Всі завершені розробки ПС ВТ є науково-технічною продукцією.

Широке застосування ВТ вимагає постійного оновлення та вдосконалення ПС. Вибір ефективних проектів ПС пов'язаний з їх економічною оцінкою та розрахунком економічного ефекту, який може визначатися як у розробника, так і в користувача.

У розробника економічний ефект виступає у вигляді чистого прибутку від реалізації ПС, що залишається в розпорядженні організації, а у користувача - у вигляді економії трудових, матеріальних і фінансових ресурсів, одержуваної за рахунок:

- Зниження трудомісткості розрахунків і алгоритмізації програмування і налагодження програм за рахунок використання ПС в процесі розробки автоматизованих систем обробки даних;

- Скорочення витрат на оплату машинного часу та інших ресурсів на налагодження програм;

- Зниження витрат на матеріали (магнітні стрічки, магнітні диски та інші матеріали);

- Прискорення введення в експлуатацію нових систем;

- Поліпшення показників основної діяльності в результаті використання ПС.

Вартісна оцінка ПС у розробників передбачає визначення розмірів витрат, що включає такі статті:

- Заробітна плата виконавців - основна і додаткова;

- Відрахування до фонду соціального захисту населення;

- Відрахування з обов'язкового страхування від нещасних випадків на виробництві та професійних захворювань;

- Витрати на матеріали і комплектуючі;

- Витрати на спецобладнання;

- Витрати на оплату машинного часу;

- Інші прямі витрати;

- Накладні витрати.

На підставі витрат розраховується собівартість і відпускна ціна ПС.

6.2.1 Вихідні дані

Таблиця 6.1 - Вихідні дані для розрахунків

Найменування показника

Одиниця виміру

Умовні позначення

Норматив

Коефіцієнт зміни швидкості обробки інформації

од.

До ск

0,7

Чисельність розробників

чол.

Ч р

1

Тарифна ставка 1-го розряду в організації

руб.

З зм 1

77000

Тарифний коефіцієнт

од.

До т

2,84

Фонд робочого часу

ч

ФРВ

169.3

Коефіцієнт природних втрат робочого часу

од.

До п

1,4

Коефіцієнт преміювання

од.

До пр

1

Норматив додаткової заробітної плати

%

Н дз

10%

Ставка відрахувань до Фонду соціального захисту населення

%

Н фсзн

34%

Ставка відрахувань з обов'язкового страхування від нещасних випадків на виробництві та професійних захворювань

%

Н БГС

1%

Ціна одного машино-години

руб.

Ц м

2200

Норматив інших витрат

%

Н пз

1 лютому%

Норматив накладних витрат

%

Н нр

1 2 0%

Норматив витрат на супровід та адаптацію

%

Н рса

10%

Рівень рентабельності

%

У рн

2 квітня%

Ставка відрахувань за єдиним нормативом у цільові бюджетні фонди з виручки від реалізації

%

Н цбф

1%

Ставка ПДВ

%

Н пдв

18%

Норматив витрат на освоєння ПС

%

Н ос

1%

Норматив витрат на поповнення обігових коштів у зв'язку з використанням нового ПС

%

Н про

1%

Ставка податку на прибуток

%

Н n р

24%

Ставка місцевих податків і зборів

%

Н мс

3%

Норматив приведення різночасних витрат

од.

Е н

0,11

6.2.2 Визначення обсягу ПС

Обсяг ПС визначається шляхом підбору аналогів на підставі класифікації типів ПС, каталогу функції ПС і аналогів ПС в розрізі функцій.

Таблиця 6.2 - Зміст і обсяг функцій на розроблювальний ПС ВТ

Функція

Обсяг, умовних машинних команд

Робота з файлами характеристик систем частинок, файлами зображень

1100

Організація введення характеристик систем частинок користувачем

1020

Організація введення керуючих сигналів від користувача

700

Організація виводу графічної інформації в режимі реального часу

1150

Інші розрахунки, сервісні функції

Липень 2000

Довідка та навчання

20 Травня

Разом

5190

На підставі інформації про функції розроблюваного ПС по каталогу функцій визначається обсяг функцій. Загальний обсяг ПС розраховується за формулою:

, (6.1)

де V о - загальний обсяг ПС, умовних машино-команд;

V i - обсяг функцій ПС, умовних машино-команд;

n - загальне число функцій.

= 5190 умовних машинних команд

З урахуванням зміни швидкості обробки інформації розраховується скоригований обсяг функцій:

V o / = V o · До ськ, (6.2)

де - Скоригований обсяг ПС, умовних машинних команд;

- Загальний обсяг ПС, умовних машинних команд;

До ск - коефіцієнт зміни швидкості обробки інформації.

V o / = 5190 * 0,7 = 3633 умовних машинних команд

6.2.3 Розрахунок трудомісткості виконуваної роботи

На підставі загального обсягу ПС визначається нормативна трудомісткість. Нормативна трудомісткість встановлюється з урахуванням складності ПС. Виділяється три групи складності, в яких враховані наступні складові ПС; мовної інтерфейсу, введення-виведення, організація даних, режим роботи, операційна і технічне середовище.

Загальна трудомісткість ПС розраховується за формулою:

, (6.3)

де Т о - загальна трудомісткість ПС, людино-днів;

Т н - нормативна трудомісткість ПС, людино-днів;

До сл - додатковий коефіцієнт складності ПС, од.

Рівень складності = 1, К СЛ = 0,18, норма часу Тн = 112. Одержуємо:

Т о = 112 * 0,7 * 0,18 = 14 людино-днів

6.2.4 Розрахунок основної заробітної плати

Нормативна трудомісткість служить базою для розрахунку основної заробітної плати.

Відповідно до "Рекомендацій щодо застосування" Єдиної тарифної сітки "робітників і службовців народного господарства" та тарифними розрядами і коефіцієнтами посад керівників організацій та обчислювальних центрів, бюджетних установ науки невиробничих галузей народного господарства кожному виконавцю встановлюється розряд і тарифний коефіцієнт.

Місячна тарифна ставка кожного виконавця визначається шляхом множення діючої місячної тарифної ставки 1-го розряду на тарифний коефіцієнт, що відповідає встановленому тарифному розряду:

З зм = С зм 1. До т, (6.4)

де С зм - тарифна ставка за місяць, руб.;

З зм 1 - тарифна ставка 1-го розряду за місяць, руб.;

До т - тарифний коефіцієнт, од.

З зм = 77000 * 2,84 = 218680 руб.

Основна заробітна плата виконавців на конкретне ПС розраховується за формулою:

(6.5)

де С оз - основна заробітна плата, руб.;

З зд - тарифна ставка за день, руб.;

Т о - загальна трудомісткість ПС, людино-днів;

До п - коефіцієнт природних втрат робочого часу, од.;

До пр - коефіцієнт преміювання, од.

З оз = (218680 / 21,25) * 14 * 1,4 * 1 = 201700 руб.

6.2.5 Розрахунок додаткової заробітної плати

Додаткова заробітна плата на конкретне ПС включає виплати, передбачені законодавством про працю (оплата відпусток, пільгових годин, часу виконання державних обов'язків та інших виплат, не пов'язаних з основною діяльністю виконавців), і визначається за нормативом у відсотках до основної заробітної плати:

, (6.6)

де С дз - додаткова заробітна плата на конкретне ПС, руб.;

Н дз - норматив додаткової заробітної плати,%.

C дз = 201700 * 0,1 = 20170 руб.

6.2.6 Розрахунок відрахувань до Фонду соціального захисту населення

Відрахування до фонду соціального захисту населення визначаються відповідно до чинних законодавчих актів за нормативом у відсотковому відношенні до фонду основної та додаткової зарплати виконавців, визначеної за нормативом, встановленому в цілому по організації:

, (6.7)

де С фсзн - сума відрахувань до Фонду соціального захисту населення, крб.

Н фсзн - норматив відрахувань до Фонду соціального захисту населення,%.

C фсзн = (201700 + 20170) * 0,34 = 75436 руб.

6.2.7 Розрахунок відрахувань по обов'язковому страхуванню від нещасних випадків на виробництві та професійних захворювань

Відрахування за обов'язковим страхуванням від нещасних випадків на виробництві та професійних захворювань розраховуються за формулою:

, (6.8)

де С БГС - сума відрахувань з обов'язкового страхування від нещасних випадків на виробництві та професійних захворювань, руб.;

Н БГС - норматив відрахувань з обов'язкового страхування від нещасних випадків на виробництві та професійних захворювань,%.

З БГС = (201700 + 20170) * 0,01 = 2219 руб.

6.2.8 Розрахунок витрат на матеріали і комплектуючі

За статтею "Матеріали" відображаються витрати на магнітні носії, папір, фарбувальні стрічки та інші матеріали, необхідні для розробки ПС. Норми витрати матеріалів у сумарному вираженні визначаються в розрахунку на 100 рядків вихідного коду. Сума витрат матеріалів розраховується за формулою:

, (6.9)

де З м - сума витрат на матеріали, руб.;

Н м - норма витрат матеріалів у розрахунку на 100 рядків вихідного коду ПС, руб.

З м = 380 * 0,7 * 3633/100 = 9664 руб.

6.2.9 Розрахунок витрат на оплату машинного часу

Витрати за статтею "Машинне час" включають оплату машинного часу, необхідного для розробки та налагодження ПС, яке визначається за нормативами (в машино-годинах) на 100 рядків вихідного коду машинного часу в залежності від характеру вирішуваних завдань і типу ПК:

, (6.10)

де С мв - сума витрат на оплату машинного часу, руб.;

Ц м - ціна одного машино-години, грн.;

Н мв - норматив витрати машинного часу на налагодження 100 рядків вихідного коду, машино-годин.

З мв = 2200 * 3633/100 * 12 * 0,6 = 575467 руб.

6.2.10 Розрахунок інших прямих витрат

Витрати на конкретне ПС включають витрати на придбання та підготовку спеціальної науково-технічної інформації та спеціальної літератури. Визначаються за нормативом у відсотках до основної заробітної плати:

, (6.11)

де С пз - сума інших витрат, руб.;

Н пз - норматив інших витрат в цілому по організації,%.

З пз = 201700 * 12/100 = 24204 руб.

6.2.11 Розрахунок накладних витрат

Дані витрати, пов'язані з необхідністю утримання апарату управління, а також з витратами на загальногосподарські потреби, розраховуються для конкретного ПС за нормативом у відсотковому відношенні до основної заробітної плати виконавців:

, (6.12)

де С нв - сума накладних витрат, руб.;

Н нв - норматив накладних витрат у цілому по організації,%.

6.2.12 Розрахунок суми витрат на розробку ПС ВТ

Загальна сума витрат на ПС розраховується за формулою:

, (6.13)

де С р - сума витрат на розробку ПС ВТ, руб.;

З р = 201700 + 20170 + 75436 + 2219 + 9664 + 0 + 575467 + 24204 + 242040 = 1150900 крб.

6.2.13 Розрахунок витрат на супровід та адаптацію

Крім того, організація-розробник здійснює витрати на супровід і адаптацію ПС, які визначаються за нормативом:

, (6.14)

де С рса - сума витрат на супровід і адаптацію ПС ВТ, руб.;

Н рса - норматив витрат на супровід і адаптацію,%.

З рса = 1150900 * 10/100 = 115 090 руб.

6.2.14 Розрахунок повної собівартості розробки ПС ВТ

Загальна сума витрат на розробку (з витратами на супроводження та адаптацію) - повна собівартість ПС - визначається за формулою:

, (6.15)

З п = 1150900 + 115090 = 1265990 крб.

6.2.15 Визначення відпускної ціни на ПС ВТ

Відпускна ціна визначається на підставі ціни розробника, яка формується на основі показника рентабельності продукції. Рентабельність і прибуток по створюваному ПС визначаються виходячи з результатів аналізу ринкових умов, переговорів з замовником (споживачем) і узгодження з ним відпускної ціни, що включає додатково податок на додану вартість і відрахування до цільових бюджетних фондів з виручки від реалізації продукції.

Прибуток розраховується за формулою:

, (6.16)

де П пс - прибуток від реалізації ПС, руб.;

У рп - рівень рентабельності ПС,%;

П пс = 1265990 * 24/100 = 303 838 руб.

Прогнозована ціна розробника ПС без податків:

Ц п = З п + П пс, (6.17)

де Ц п - прогнозована ціна розробника ПС, руб.;

Ц п = 1265990 + 303838 = 1569828 крб.

Сума відрахувань до цільових бюджетних фондів з виручки від реалізації продукції єдиним платежем:

, (6.18)

де С цбф - сума відрахувань до цільових бюджетних фондів з виручки від реалізації продукції єдиним платежем, руб.;

Н цбф - ставка відрахувань у цільові бюджетні фонди з виручки від реалізації продукції єдиним платежем,%.

З цбф = 1569828 * 1 / (100-1) = 15857 руб.

Сума податку на додану вартість:

, (6.19)

де ПДВ - сума податку на додану вартість, руб.;

Н пдв - ставка ПДВ,%.

ПДВ = (1569828 + 15857) * 18/100 = 285 423 руб.

Прогнозована відпускна ціна:

, (6.20)

де Ц о - прогнозована відпускна ціна, крб.

Ц о = 1569828 + 15857 + 285423 = 1871108 крб.

6.3 Розрахунок економічного ефекту від застосування ПС у користувача

Створювані програмні засоби можуть призначатися як для зовсім нових, раніше не розв'язувалися або розв'язувалися ручним способом завдань, так і для традиційних завдань, що вирішуються за допомогою програмних засобів, які можна вдосконалювати.

У результаті застосування нового ПС користувач може понести значні капітальні витрати на придбання та освоєння ПС, доукомплектування ЕОМ новими технічними засобами і поповнення оборотних коштів. Однак, якщо придбане ПС буде в достатній мірі ефективніше базового, то додаткові капітальні витрати швидко окупляться. Ефект може бути досягнутий за рахунок скорочення обсягу ПС (зменшення кількості машинних команд, кількості рядків і т.д.), зниження трудомісткості підготовки даних, обробки інформації, аналізу результатів, зменшення витрат машинного часу і матеріалів.

Для визначення економічного ефекту від використання нового ПС у споживача необхідно порівняти витрати по всіх основних статтях витрат на експлуатацію нового ПС (витрати на заробітну плату з нарахуваннями, матеріали, машинне час) з витратами за відповідними статтями базового варіанту. При цьому за базовий варіант слід приймати аналогічне програмний засіб, що використовується в діючій автоматизованій системі. При порівнянні базового і нового варіантів ПС як економічного ефекту буде виступати загальна економія всіх видів ресурсів щодо базового варіанту. При цьому створення нового ПС виявиться економічно доцільним лише в тому випадку, якщо всі капітальні витрати окупляться за рахунок одержуваної економії в найближчі 1-2 роки.

6.3.1 Вихідні дані

Таблиця 6.3 - Вихідні дані для порівняння варіантів

Найменування показників

Позначення

Одиниці виміру

Значення показника

Найменування джерела інформації




в базовому варіанті

в новому варіанті


Середня трудомісткість робіт у розрахунку на 100 рядків коду

Т з 1

Т з 2

людино-днів з на 100 рядків коду

0,96

0,92

За даними користувача

Середня витрата машинного часу в розрахунку на 100 рядків коду

Н мв 1

Н мв 2

машино-година на 100 рядків коду

7, 7

7, 2

За даними користувача

Середня витрата матеріалів у розрахунку на

100 рядків коду

З м 1

З м 2

руб. на 100 рядків коду

341

2 66

За даними користувача

Обсяг робіт залежно від функціональної групи і призначення ПС визначається за формулою:

А = V о '∙ К пс, (6.21)

де V о '- скоригований обсяг ПС, умовних машино-команд;

До пс - коефіцієнт застосування ПС, од.

Таким чином, A = 3633 * 0,7 = 2543 умовних машинних команд

6.3.2 Розрахунок капітальних витрат замовника ПС

Загальні капітальні вкладення замовника (споживача), пов'язані з придбанням, впровадженням та використанням ПС, розраховуються за формулою:

К о = К пр + Кос + К об, (6.22)

де К пр - витрати користувача на придбання ПС за відпускною ціною розробника з урахуванням вартості послуг з експлуатації і супроводу, руб.;

Кос - витрати користувача на освоєння ПС, руб.;

До про - витрати на поповнення оборотних коштів у зв'язку з використанням нового ПС, руб.

Витрати на освоєння ПС і на поповнення оборотних коштів рекомендується розраховувати за формулами:

Кос = К пр ∙ Н ос, (6.23)

До об = К пр ∙ Н про, (6.24)

До пр = Ц о = 1871108

До ос = 1871108 * 0,01 = 18711 руб.

До об = 1871108 * 0,01 = 18711 руб.

К о = 1871108 + 18711 + 18711 = 1908530 крб.

6.3.3 Розрахунок економії основних видів ресурсів у зв'язку з використанням нового ПС

Економія витрат на заробітну плату при використанні нового ПС в розрахунку на обсяг виконаних робіт:

Е оз = Е оз '∙ А, (6.25)

де Е оз - економія витрат на заробітну плату при вирішенні завдань з використанням нового ПС, руб.;

Е оз '- економія витрат на заробітну плату при вирішенні завдань з використанням нового ПС в розрахунку на 100 КБ, руб.;

А - обсяг виконаних робіт з використанням нового ПС, 100 КБ.

Економія витрат на заробітну плату у розрахунку на 100 КБ:

, (6.26)

де С зм - середньомісячна заробітна плата одного програміста, руб.;

Т з1, Т с2 - трудомісткість робіт у розрахунку на 100 рядків коду при базовому і новому варіанті відповідно, людино-годин;

Т ч - кількість годин роботи в день, год;

ФРВ - фонд робочого часу за місяць, ч.

Т с2 = 0,3 * 112 * 100/3633 = 0,92 людино-днів

Е оз '= 218680 * 0,04 / 169,3 = 52 руб.

Е оз = 52 * 2543 = 131389 руб.

При визначенні трудомісткості, пов'язаної з використанням програми рекомендується орієнтуватися на показник рівний 30-50% від трудомісткості розробки в годинах.

Економія нарахувань на заробітну плату при використанні нового ПС в розрахунку на обсяг виконаних робіт:

Е поч = Е оз ∙ До поч, (6.27)

де Е поч - економія нарахувань на заробітну плату при вирішенні завдань з використанням нового ПС, руб.;

До поч - коефіцієнт нарахувань на заробітну плату, од.

, (6.28)

До поч = (34 + 1) / 100 = 0,35 од.

Е поч = 131389 * 0,35 = 45986 руб.

Економія витрат на оплату машинного часу в розрахунку на виконаний обсяг робіт у результаті застосування нового ПС:

, (6.29)

де Е мв - економія витрат на оплату машинного часу при вирішенні завдань з використанням нового ПС, руб.;

- Економія витрат на оплату машинного часу при вирішенні завдань з використанням нового ПС в розрахунку на 100 КБ, руб.

Економія витрат на оплату машинного часу у розрахунку на 100 КБ:

, (6.30)

де Н мв1, Н мв2 - середня витрата машинного часу у розрахунку на 100 КБ при застосуванні базового і нового варіанту ПС відповідно, машино-годин.

Е мв '= 2200 * 0,5 = 1100 руб.

Е мв = 1100 * 2543 = 2797300 крб.

Економія витрат на матеріали при використанні нового ПС в розрахунку на обсяг виконаних робіт:

, (6.31)

де Е м - економія витрат на матеріали при використанні нового ПС, руб.;

Е м '- економія витрат на матеріали в розрахунку на 100 КБ при використанні нового ПС, руб.:

, (6.32)

де С м1, З м2 - середня витрата матеріалів у користувача в розрахунку на 100 КБ при використанні базового і нового варіанту ПС відповідно, руб.

Е м '= 341-266 = 75 руб.

Е м = 75 * 2543 = 190725 руб.

Загальна річна економія поточних витрат, пов'язаних з використанням нового ПС:

, (6.33)

Е о = 131389 + 45986 + 2797300 + 190725 = 3165400 крб.

6.3.4 Розрахунок економічного ефекту

Впровадження нового ПС дозволить користувачеві заощадити на поточних витратах, тобто практично отримати на цю суму додатковий прибуток. Для користувача в якості економічного ефекту виступає лише чистий прибуток - додатковий прибуток, що залишається в його розпорядженні Пч), яка визначаються за формулою:

, (6.34)

де ΔП год - приріст чистого прибутку, крб.

Н мс - ставка місцевих податків і зборів,%.

, (6.35)

де ΔП - приріст прибутку, крб.

Н п - ставка податку на прибуток,%.

= 3165400 - 3165400 * 24/100 = 2405704 крб.

= 2405704 - 2405704 * 3 / 100 = 2333533 крб.

У процесі використання нового ПС чистий прибуток у кінцевому підсумку відшкодовує капітальні витрати. Однак, отримані при цьому суми результатів (прибутку) і витрат (капітальних вкладень) за роками призводять до єдиного часу - розрахункового року (за розрахунковий рік прийнятий 2008 рік) шляхом множення результатів і витрат за кожний рік на коефіцієнт привиди (ALFA t), який розраховується за формулою:

, (6.36)

де Ен - норматив привиди різночасних витрат і результатів;

t p - розрахунковий рік, t p = 1;

t - номер року, результати і витрати якого приводяться до розрахункового (2008-1, 2009-2, 2010-3, 2011-4).

Норматив приведення різночасних витрат і результатів (Е н) для програмних засобів ОТ в існуючій практиці приймається рівним 0,12. При такому нормативі коефіцієнтами приведення (ALFA t) за роками будуть відповідати наступні значення:

ALPHA 1 = (1 +0,15) 1-1 = 1

ALPHA 2 = (1 +0,15) 1-2 = 0,870

ALPHA 3 = ​​(1 +0,15) 1-3 = 0,756

ALPHA 4 = (1 +0,15) 1-4 = 0,658

Дані розрахунку економічного ефекту зведемо в таблицю:

Таблиця 6.4 - Розрахунок економічного ефекту від використання нового ПС

Показники

Од.

вимірювання

Методика розрахунку

2008

2009

2010

2011

Результати:







Приріст прибутку за рахунок економії витрат

руб.

Δ П ч

2333533

2333533

2333533

2333533

Сума прибутку з урахуванням фактору часу

руб.

Δ П ч ∙ ALFA t

2333533

2030174

1764151

1535465

Витрати:







Витрати на придбання ПС

руб.

До пр

1871108

-

-

-

Витрати на освоєння ПС

руб.

Кос

18711

-

-

-

Витрати на доукомплектування ВТ технічними засобами

руб.

До тс

-

-

-

-

Витрати на поповнення оборотних коштів

руб.

До про

18711

18711

18711

18711

Сума витрат

руб.

К о

1908530

18711

18711

18711

Сума витрат з урахуванням фактора часу

руб.

К о ∙ ALFA t

1908530

16279

14146

12312

Економічний ефект

руб.

Δ П ч ∙ ALFA t-К о ∙ ALFA t


425003


2013895

1750005

1523153

Економічний ефект з наростаючим підсумком

руб.



425003

2438898

4188903

5712056

Коефіцієнт приведення

од.

ALFA t

1

0,870

0,756

0,658

6.4 Результати оцінки економічної доцільності

У даному розділі була розрахована відпускна ціна програмного засобу, яка склала 1871108 крб. Витрати споживача, пов'язані з придбанням, освоєнням програмного засобу, а також поповненням обігових коштів - 1951267 крб. Приріст прибутку за рахунок економії нарахувань на заробітну плату, оплати машинного часу і матеріалів в кожен з розрахункових років склав відповідно 2333533 крб., 2030174 крб., 1764151 крб. і 1535465 крб. Витрати споживача окупилися вже у перший рік, при цьому вийшов позитивний економічний ефект у розмірі 425003 руб. Економічний ефект за 4 роки використання ПС складе 5712056 крб. Все це дає можливість говорити про те, що створення і впровадження ПС доцільно.

Висновок

У представленому дипломному проекті розроблено графічний редактор ефектів частинок "Easy Particles".

При розробці були використані найсучасніші підходи до проектування програмного забезпечення. Програмне забезпечення розроблене з урахуванням простоти майбутньої модифікації.

Програма має зручний користувальницький інтерфейс, що відповідає сучасним вимогам. Вона може використовуватися на різних комп'ютерах з різною конфігурацією і не потребує багато ресурсів. Для користувача інтерфейс програми розрахований на мінімальні навички роботи з комп'ютером.

У ході виконання поставленого завдання реалізовані всі основні функції програмного засобу. Всі пропоновані до програми вимоги були виконані. Налагодження і тестування програми проведено успішно.

Проведено техніко-економічне обгрунтування впровадження спроектованої системи. Отриманий економічний ефект дозволяє окупити витрати користувача на закупівлю, встановлення ПС, навчання співробітників його використання та інші. Отже, розробка є економічно доцільною.

Мета, поставлена ​​перед автором роботи, була виконана в повній мірі. Проект виконаний у відповідність до державних стандартів і вимог, що пред'являються до технічної документації.

Як вже було сказано, розроблена версія програми є першою реалізацією, найбільш загальної, що дозволяє використовувати лише самі основні величини і оперувати сильно обмеженим безліччю настройок і характеристик.

Плановане майбутнє розширення повинно торкнутися, в першу чергу, користувальницького інтерфейсу, а також задаються параметрів частинок і емітерів. З метою більшої зручності використання редактора, в нього планується внести зміни, пов'язані зі способами завдання швидкості частинок і гравітації, діючої на них. Можливо, буде введено параметри дисперсії гравітації, або інші параметри, що задають зміну значень гравітації. Самі значення швидкості і гравітації планується вводити шляхом векторів.

Необхідно змінити способи завдання зміни кольору часток (через візуальний колірної елемент управління), ввести можливість використання додаткових ключів кольору, з урахуванням тривалості переходу частки від одного кольору до іншого.

Аналогічні параметри-ключі (і візуальні елементи управління, відповідні їм) будуть введені для розмірів часток.

Для розмірів, кольору, затримки генерації часток планується ввести параметри дисперсії.

Деякі зміни зазнає і віконна система додатки. У ній будуть переважати перетаскується приєднуються панелі. Стане можливим зміна розмірів вікна виведення, а також використання повноекранного режиму при перегляді ефектів.

Серед інших можливих змін можна відзначити запуск у вікні перегляду; додавання ефектів часток у файли відео, а також розширені програмні інтерфейси для розробників комп'ютерних ігор та інших графічних додатків.

Перераховані зміни мають підвищити інтерес до програмного засобу та його корисність для різних груп користувачів.

Список використаних джерел

1) Бьерн Страуструп Дизайн і еволюція мови C + + - М.: ДМК прес, 2006. - 448с.

2) Єфремова О.С. Вимоги охорони праці при роботі на персональних електронно-обчислювальних машинах (ПК) - М.: Альфа-прес, 2005. - 150с.

4) Санітарні норми для освітніх установ. - 5-е вид., Доп. - М.: Освіта в документах, 2002. - 200с.

5) Замбржіцкій О.М. Гігієнічна оцінка природного та штучного освітлення приміщень. - Мн.: БДМУ, 2005. - 18 с.

6) СанПіН N 9-131 РБ 2000 Гігієнічні вимоги до відеодисплейних терміналів (ВДТ), електронно-обчислювальних машин (ЕОМ) та організації роботи

7) Косіліна Н.І., Колтановского А.П. Виробнича гімнастика для працівників розумової праці - М.: Фізкультура і спорт, 1983.

8) Кляуззе В.П. Безпека & комп'ютер. - Мн.: В. П. Кляуззе, 2001. - 155с.

Додаток А

(Обов'язковий)

Текст програмного модуля обробки частинок

/ / ParticleSystemChain.cpp (черга емітерів)

# Include "ParticleSystemChain.h"

# Include "PSOutputFrame.h" / / just for using canvas to get current reflecting mode ang zoom

# Define BLEND_SRC "blend_src"

# Define BLEND_DST "blend_dst"

# Define ITEM_SELECTED "item_selected"

# Define PSBOUND_SELECTED_COLOR wxColour (200, 200, 200, 255)

# Define PSBOUNS_CHOOSED_COLOR wxColour (70, 70, 70, 255)

# Define PSBOUND_COLOR wxColour (50, 50, 50, 255)

# Define MIN_RUN_PSCHAIN_ITEM_DIMENSION 20

ParticleSystemChain * ParticleSystemChain:: singletonChain = NULL;

ParticleSystemChain * ParticleSystemChain:: Master ()

{

if (! singletonChain)

singletonChain = new ParticleSystemChain ();

return singletonChain;

}

void ParticleSystemChain:: CleanSingleton ()

{

if (singletonChain)

{

delete singletonChain;

singletonChain = NULL;

}

}

int ParticleSystemChain:: AddSystem ()

{

ParticleSystem * ps = new ParticleSystem ();

all_ps.push_back (ps);

if (workMode! = ParticleSystemChainWorkMode_STATIC)

ps-> start ();

int new_ps_layer = (int) all_ps.size () - 1;

if (selectedSystemLayer <0)

selectedSystemLayer = new_ps_layer;

return new_ps_layer;

}

bool ParticleSystemChain:: RemoveSystemAtLayer (int layer)

{

if ((layer <0) | | (layer> = (int) all_ps.size ()))

return false;

delete all_ps.at (layer);

all_ps.erase (all_ps.begin () + layer);

if (layer == choosedSystemLayer)

choosedSystemLayer = -1;

if (all_ps.size () == 0)

selectedSystemLayer = -1;

else

if (selectedSystemLayer> = layer & & selectedSystemLayer> 0)

selectedSystemLayer -;

return true;

}

void ParticleSystemChain:: RemoveAll ()

{

vector <ParticleSystem*>:: iterator iter = all_ps.begin ();

while (iter! = all_ps.end ())

{

delete ((ParticleSystem *) * iter);

+ + Iter;

}

all_ps.clear ();

selectedSystemLayer = choosedSystemLayer = -1;

}

void ParticleSystemChain:: MoveSystem (int from, int to)

{

int numof_systems = (int) all_ps.size ();

if ((from == to) | | (from <0) | | (from> = numof_systems) | | (to <0) | | (to> = numof_systems))

return;

ParticleSystem * tmp_ps_ptr = all_ps.at (from);

all_ps.erase (all_ps.begin () + from);

all_ps.insert (all_ps.begin () + to, tmp_ps_ptr);

}

void ParticleSystemChain:: CopySystemsData (int layer_from, int layer_to)

{

int numof_systems = (int) all_ps.size ();

if (layer_from == layer_to | | layer_from <0 | | layer_from> = numof_systems | | layer_to <0 | | layer_to> = numof_systems)

return;

all_ps.at (layer_to) -> copyDataFromParticleSystem (all_ps.at (layer_from));

}

bool ParticleSystemChain:: Save (TiXmlElement * root) const

{

TiXmlElement tmp ("BLENDING");

TiXmlElement * caption = (TiXmlElement *) root-> InsertEndChild (tmp);

if (! caption)

return false;

caption-> SetAttribute (BLEND_SRC, blendModeSrc);

caption-> SetAttribute (BLEND_DST, blendModeDst);

return saveSystems (root);

}

bool ParticleSystemChain:: Load (TiXmlElement * root)

{

TiXmlElement * blending_attrs_ptr = (TiXmlElement *) root-> FirstChild ("BLENDING");

if (! blending_attrs_ptr) / / old version file (1.0), just set defaults

{

blendModeSrc = GL_ONE;

blendModeDst = GL_ONE_MINUS_SRC_ALPHA;

}

else

{

blending_attrs_ptr-> Attribute (BLEND_SRC, & blendModeSrc);

blending_attrs_ptr-> Attribute (BLEND_DST, & blendModeDst);

}

return loadSystems (root);

}

ParticleSystemOutputCoordCharacter ParticleSystemChain:: AnalyseOutputCoords (MYPoint2D point) const

{

ParticleSystemOutputCoordCharacter res;

res.psLayer = -1;

res.isLeft = res.isRight = res.isTop = res.isBottom = false;

/ / First find selecting system layer

vector <ParticleSystem*>:: const_iterator iter = all_ps.end ();

vector <ParticleSystem*>:: const_iterator begin_iter = all_ps.begin ();

size_t i = all_ps.size ();

wxRect system_rect, tmp_rect;

bool chain_is_run = (workMode! = ParticleSystemChainWorkMode_STATIC);

while (iter! = begin_iter)

{

- Iter, - i;

wxRect tmp_rect;

MYPoint2D appear_box_position = MYPoint2DMake ((* iter) -> getX (), (* iter) -> getY ());

MYSize2D appear_box_size = (* iter) -> getAppearBoxSize ();

if (chain_is_run)

{

tmp_rect = wxRect (appear_box_position.x, appear_box_position.y, appear_box_size.width, appear_box_size.height);

if (tmp_rect.GetWidth () <MIN_RUN_PSCHAIN_ITEM_DIMENSION)

{

int diff = MIN_RUN_PSCHAIN_ITEM_DIMENSION - tmp_rect.GetWidth ();

tmp_rect.SetX (tmp_rect.GetX () - diff / 2);

tmp_rect.SetWidth (MIN_RUN_PSCHAIN_ITEM_DIMENSION);

}

if (tmp_rect.GetHeight () <MIN_RUN_PSCHAIN_ITEM_DIMENSION)

{

int diff = MIN_RUN_PSCHAIN_ITEM_DIMENSION - tmp_rect.GetHeight ();

tmp_rect.SetY (tmp_rect.GetY () - diff / 2);

tmp_rect.SetHeight (MIN_RUN_PSCHAIN_ITEM_DIMENSION);

}

}

else

tmp_rect = wxRect (appear_box_position.x - BOUND_DIMENSION, appear_box_position.y - BOUND_DIMENSION,

appear_box_size.width + BOUND_DIMENSION * 2, appear_box_size.height + BOUND_DIMENSION * 2);

if (point.x> = tmp_rect.x & & point.x <(tmp_rect.x + tmp_rect.width) & &

point.y> = tmp_rect.y & & point.y <(tmp_rect.y + tmp_rect.height))

{

res.psLayer = (int) i;

system_rect = tmp_rect;

break;

}

}

if (res.psLayer == -1 / * no selected ps * / | | chain_is_run)

return res;

/ / Selecting system has been finded, and <! ChainIsRun> - maybe we touched on some ps's bottom (-s)

if ((point.x> = system_rect.x) & & (point.x <system_rect.x + BOUND_DIMENSION))

res.isLeft = true;

if ((point.x <system_rect.x + system_rect.width) & & (point.x> = system_rect.x + system_rect.width - BOUND_DIMENSION))

res.isRight = true;

if ((point.y> = system_rect.y) & & (point.y <system_rect.y + BOUND_DIMENSION))

res.isTop = true;

if ((point.y <system_rect.y + system_rect.height) & & (point.y> = system_rect.y + system_rect.height - BOUND_DIMENSION))

res.isBottom = true;

return res;

}

void ParticleSystemChain:: ChooseSystemAtLayer (int layer)

{

if ((layer <0) | | (layer> = (int) all_ps.size ()))

choosedSystemLayer = -1;

else

choosedSystemLayer = layer;

}

int ParticleSystemChain:: GetChoosedSystemLayer () const

{

return choosedSystemLayer;

}

void ParticleSystemChain:: SelectSystemAtLayer (int layer)

{

if ((layer <0) | | (layer> = (int) all_ps.size ()))

selectedSystemLayer = -1;

else

selectedSystemLayer = layer;

}

int ParticleSystemChain:: GetSelectedSystemLayer () const

{

return selectedSystemLayer;

}

ParticleSystemChainWorkMode ParticleSystemChain:: GetWorkMode () const

{

return workMode;

}

void ParticleSystemChain:: SetWorkMode (ParticleSystemChainWorkMode mode)

{

vector <ParticleSystem*>:: iterator begin_iter = all_ps.begin ();

vector <ParticleSystem*>:: iterator end_iter = all_ps.end ();

vector <ParticleSystem*>:: iterator iter = begin_iter;

if (mode == ParticleSystemChainWorkMode_PLAYBACK | | mode == ParticleSystemChainWorkMode_PLAYBACK_LOOP)

{

while (iter! = end_iter)

{

(* Iter) -> start ();

+ + Iter;

}

timer.reset ();

}

else / / if (mode == ParticleSystemChainWorkMode_STATIC)

{

while (iter! = end_iter)

{

(* Iter) -> stopExtra ();

+ + Iter;

}

}

workMode = mode;

}

void ParticleSystemChain:: CallbackSystems ()

{

if (workMode == ParticleSystemChainWorkMode_STATIC)

return;

double sec_interval = timer.getMilliseconds () / 1000.0;

timer.reset ();

vector <ParticleSystem*>:: iterator iter = all_ps.begin ();

bool chain_is_run = false;

while (iter! = all_ps.end ())

{

(* Iter) -> callback (sec_interval);

if (! (* iter) -> isFinished ())

chain_is_run = true;

+ + Iter;

}

if (chain_is_run)

return;

/ /! Chain_is_run

if (workMode == ParticleSystemChainWorkMode_PLAYBACK)

SetWorkMode (ParticleSystemChainWorkMode_STATIC);

else / / if (workMode == ParticleSystemChainWorkMode_PLAYBACK_LOOP)

SetWorkMode (ParticleSystemChainWorkMode_PLAYBACK_LOOP); / / just restart

}

void ParticleSystemChain:: DrawSystems ()

{

vector <ParticleSystem*>:: iterator iter = all_ps.begin ();

if (workMode! = ParticleSystemChainWorkMode_STATIC)

{

glEnable (GL_BLEND);

glBlendFunc (blendModeSrc, blendModeDst);

while (iter! = all_ps.end ())

{

(* Iter) -> draw ();

+ + Iter;

}

glDisable (GL_BLEND);

}

else

{

int i = 0;

while (iter! = all_ps.end ())

{

ParticleSystem * curr_ps = (* iter);

if (i == selectedSystemLayer)

curr_ps-> setBoundColor (PSBOUND_SELECTED_COLOR);

else if (i == choosedSystemLayer)

curr_ps-> setBoundColor (PSBOUNS_CHOOSED_COLOR);

else

curr_ps-> setBoundColor (PSBOUND_COLOR);

curr_ps-> drawBound ();

+ + Iter, + + i;

}

}

}

int ParticleSystemChain:: GetBlendModeSrc () const

{

return blendModeSrc;

}

int ParticleSystemChain:: GetBlendModeDst () const

{

return blendModeDst;

}

void ParticleSystemChain:: SetBlendModeSrc (int mode)

{

blendModeSrc = mode;

}

void ParticleSystemChain:: SetBlendModeDst (int mode)

{

blendModeDst = mode;

}

ParticleSystem * ParticleSystemChain:: GetSystemAtLayer (int layer)

{

if (layer <0 | | layer> = (int) all_ps.size ())

return NULL;

return all_ps.at (layer);

}

MYRect ParticleSystemChain:: GetInitialSystemsRect (unsigned int * systems_counter) const / / systems bound rect on gl

{

* Systems_counter = (unsigned int) all_ps.size ();

double min_x = 0.0;

double min_y = 0.0;

double max_x = 0.0;

double max_y = 0.0;

vector <ParticleSystem*>:: const_iterator begin_iter = all_ps.begin ();

vector <ParticleSystem*>:: const_iterator end_iter = all_ps.end ();

vector <ParticleSystem*>:: const_iterator iter = begin_iter;

while (iter! = end_iter)

{

bool thereis_begin_ps = (iter == begin_iter);

if (thereis_begin_ps | | min_x> (* iter) -> data.initialX)

min_x = (* iter) -> data.initialX;

if (thereis_begin_ps | | min_y> (* iter) -> data.initialY)

min_y = (* iter) -> data.initialY;

double new_max = (* iter) -> data.initialX + (* iter) -> data.pAppearBoxSize.width;

if (thereis_begin_ps | | max_x <new_max)

max_x = new_max;

new_max = (* iter) -> data.initialY + (* iter) -> data.pAppearBoxSize.height;

if (thereis_begin_ps | | max_y <new_max)

max_y = new_max;

+ + Iter;

}

MYPoint2D pos = MYPoint2DMake (min_x, min_y);

MYSize2D sz = MYSize2DMake (max_x - min_x, max_y - min_y);

return (MYRectMake (pos, sz));

}

int ParticleSystemChain:: GetNumofSystems () const

{

return (int) all_ps.size ();

}

/ / Internals

ParticleSystemChain:: ParticleSystemChain ()

{

workMode = DEFAULT_PARTICLE_SYSTEM_CHAIN_WORK_MODE;

blendModeSrc = GL_ONE;

blendModeDst = GL_ONE_MINUS_SRC_ALPHA;

selectedSystemLayer = choosedSystemLayer = -1;

}

ParticleSystemChain:: ~ ParticleSystemChain ()

{

RemoveAll ();

}

bool ParticleSystemChain:: saveSystems (TiXmlElement * root) const

{

TiXmlElement tmp ("SYSTEMS_DATA");

TiXmlElement * sys_data = (TiXmlElement *) root-> InsertEndChild (tmp);

if (! sys_data)

return false;

sys_data-> SetAttribute (ITEM_SELECTED, selectedSystemLayer);

if (all_ps.size () == 0)

return true;

vector <ParticleSystem*>:: const_iterator iter = all_ps.end ();

do

{

- Iter;

if (! (* iter) -> save (root))

return false;

}

while (iter! = all_ps.begin ());

return true;

}

bool ParticleSystemChain:: loadSystems (TiXmlElement * root)

{

TiXmlElement * systems_data_ptr = (TiXmlElement *) root-> FirstChild ("SYSTEMS_DATA");

int selected_system_layer = -1;

if (systems_data_ptr) / / new format file (ver. above 1.0)

systems_data_ptr-> Attribute (ITEM_SELECTED, & selected_system_layer);

vector <ParticleSystem*> tmp_all_ps;

ParticleSystem * tmp_ps_ptr = new ParticleSystem ();

while (bool is_success = tmp_ps_ptr-> load (root))

{

tmp_all_ps.insert (tmp_all_ps.begin (), tmp_ps_ptr);

tmp_ps_ptr = new ParticleSystem ();

}

delete tmp_ps_ptr;

if (tmp_all_ps.size ()> 0 & & selected_system_layer <0)

selectedSystemLayer = 0;

else

selectedSystemLayer = selected_system_layer;

/ / Remove all old-created and add new

vector <ParticleSystem*>:: iterator iter = all_ps.begin ();

while (iter! = all_ps.end ())

{

delete ((ParticleSystem *) * iter);

+ + Iter;

}

all_ps.clear ();

tmp_all_ps.swap (all_ps);

workMode = ParticleSystemChainWorkMode_STATIC;

return true;

}

/ / ParticleSystem.cpp (емітер)

# Include "ParticleSystem.h"

# Include "MYSpinCtrld.h"

# Define PS_BOUNDED_RECT_COLOR wxColour (150, 150, 150, 255)

/ / XML element's attributes of PSs

# Define TEXTURE_ATTR "texture_file_name"

# Define LIFE_TIME_ATTR "life_time"

# Define APPEAR_DELAY_ATTR "appear_delay"

# Define PARTICLE_SPEED_X_ATTR "particle_speed_x"

# Define PARTICLE_SPEED_Y_ATTR "particle_speed_y"

# Define GRAVITY_X_ATTR "gravity_x"

# Define GRAVITY_Y_ATTR "gravity_y"

# Define MAX_COUNT_ATTR "max_count"

# Define START_COUNT_ATTR "start_count"

# Define APPEAR_BOX_W_ATTR "appear_box_w"

# Define APPEAR_BOX_H_ATTR "appear_box_h"

# Define RED_BEGIN_ATTR "red_begin"

# Define RED_END_ATTR "red_end"

# Define GREEN_BEGIN_ATTR "green_begin"

# Define GREEN_END_ATTR "green_end"

# Define BLUE_BEGIN_ATTR "blue_begin"

# Define BLUE_END_ATTR "blue_end"

# Define ALPHA_BEGIN_ATTR "alpha_begin"

# Define ALPHA_END_ATTR "alpha_end"

# Define SCALE_BEGIN_W_ATTR "scale_begin_w"

# Define SCALE_BEGIN_H_ATTR "scale_begin_h"

# Define SCALE_END_W_ATTR "scale_end_w"

# Define SCALE_END_H_ATTR "scale_end_h"

# Define DISPERSION_X_ATTR "dispersion_x"

# Define DISPERSION_Y_ATTR "dispersion_y"

# Define PS_X_ATTR "ps_x"

# Define PS_Y_ATTR "ps_y"

# Define PS_SPEED_X_ATTR "ps_speed_x"

# Define PS_SPEED_Y_ATTR "ps_speed_y"

# Define START_DELAY_ATTR "start_delay"

# Define STOP_DELAY_ATTR "stop_delay"

# Define ROTATE_ATTR "rotate"

/ / Ctors, destructors, ...

ParticleSystem:: ParticleSystem ()

{

data.pLifeTime = 1.0;

data.pMaxCount = EXPL_MAX;

data.pCountOnStart = 1;

data.pGravityX = data.pGravityY = 0.0;

/ / P.speed, dispersion page

data.pMoveSpeedX = 0.0;

data.pMoveSpeedY = 0.0;

data.pKFDispersionX = 0.0;

data.pKFDispersionY = 0.0;

/ / P.scale page

data.pKFScaleBeginW = 1.0;

data.pKFScaleBeginH = 1.0;

data.pKFScaleEndW = 1.0;

data.pKFScaleEndH = 1.0;

/ / P.color page

data.pRedBegin = 1.0;

data.pGreenBegin = 1.0;

data.pBlueBegin = 1.0;

data.pAlphaBegin = 1.0;

data.pRedEnd = 1.0;

data.pGreenEnd = 1.0;

data.pBlueEnd = 1.0;

data.pAlphaEnd = 1.0;

/ / Rotate

data.pAngleRotate = 0.0;

/ / Start in, stop in page

data.startDelay = 0.0;

data.stopDelay = 1800.0;

data.pAppearDelay = 0.0;

/ / PS settings page

MYSize2D sz = {100.0,100.0};

data.pAppearBoxSize = sz;

data.speedChangeX = 0;

data.speedChangeY = 0;

data.initialX = currentX = BOUND_DIMENSION;

data.initialY = currentY = BOUND_DIMENSION;

boundedRectColor = PS_BOUNDED_RECT_COLOR;

particleTexPtr = NULL;

setDefaultParticleTex ();

isRunb = false;

isFinishedb = false;

viewMatrixCache = (GLdouble *) malloc (sizeof (GLdouble) * 16);

assert (viewMatrixCache! = NULL);

}

ParticleSystem:: ~ ParticleSystem ()

{

free (viewMatrixCache);

if (particleTexPtr)

delete particleTexPtr;

}

int ParticleSystem:: setParticleTex (const wxString & texture_path)

{

MYTexture * tmp_tex = new MYTexture (texture_path);

int res = tmp_tex-> getState ();

if (res! = TEX_OK)

{

delete tmp_tex;

return res;

}

if (particleTexPtr)

delete particleTexPtr;

particleTexPtr = tmp_tex;

data.particleTexFileName = texture_path;

MYTexCoordPoint * ptrTex = texCoord;

for (int i = 0; i <EXPL_MAX; i + +)

{

ptrTex-> x = 0.0; ptrTex-> y = 0.0;

ptrTex + +;

ptrTex-> x = particleTexPtr-> getMaxS (); ptrTex-> y = 0.0;

ptrTex + +;

ptrTex-> x = particleTexPtr-> getMaxS (); ptrTex-> y = particleTexPtr-> getMaxT ();

ptrTex + +;

ptrTex-> x = 0.0; ptrTex-> y = 0.0;

ptrTex + +;

ptrTex-> x = particleTexPtr-> getMaxS (); ptrTex-> y = particleTexPtr-> getMaxT ();

ptrTex + +;

ptrTex-> x = 0.0; ptrTex-> y = particleTexPtr-> getMaxT ();

ptrTex + +;

}

return TEX_OK;

}

void ParticleSystem:: setDefaultParticleTex ()

{

if (particleTexPtr)

delete particleTexPtr;

GLubyte * buffer = new GLubyte [8 * 8 * 4];

memset (buffer, 255, 8 * 8 * 4); / / white colour

particleTexPtr = new MYTexture (32,16711680 / * third byte pattern * /, 65280 / * second byte pattern * /, 255 / * first byte pattern * /

, 8,8, buffer);

delete [] buffer;

data.particleTexFileName = wxString ("");

}

double ParticleSystem:: getX () const

{

return currentX;

}

double ParticleSystem:: getY () const

{

return currentY;

}

void ParticleSystem:: setX (double x)

{

data.initialX = currentX = x;

}

void ParticleSystem:: setY (double y)

{

data.initialY = currentY = y;

}

double ParticleSystem:: getSpeedChangeX () const

{

return data.speedChangeX;

}

double ParticleSystem:: getSpeedChangeY () const

{

return data.speedChangeY;

}

void ParticleSystem:: setSpeedChangeX (double speed)

{

data.speedChangeX = speed;

}

void ParticleSystem:: setSpeedChangeY (double speed)

{

data.speedChangeY = speed;

}

double ParticleSystem:: getStopDelay () const

{

return data.stopDelay;

}

double ParticleSystem:: getStartDelay () const

{

return data.startDelay;

}

void ParticleSystem:: setStopDelay (double time)

{

data.stopDelay = time;

}

void ParticleSystem:: setStartDelay (double time)

{

data.startDelay = time;

}

double ParticleSystem:: getLifeTime () const

{

return data.pLifeTime;

}

void ParticleSystem:: setLifeTime (double time)

{

data.pLifeTime = time;

}

double ParticleSystem:: getParticleAppearDelay () const

{

return data.pAppearDelay;

}

void ParticleSystem:: setParticleAppearDelay (double time)

{

data.pAppearDelay = time;

}

double ParticleSystem:: getMoveSpeedX () const

{

return data.pMoveSpeedX;

}

double ParticleSystem:: getMoveSpeedY () const

{

return data.pMoveSpeedY;

}

void ParticleSystem:: setMoveSpeedX (double speed)

{

data.pMoveSpeedX = speed;

}

void ParticleSystem:: setMoveSpeedY (double speed)

{

data.pMoveSpeedY = speed;

}

double ParticleSystem:: getGravityX () const

{

return data.pGravityX;

}

double ParticleSystem:: getGravityY () const

{

return data.pGravityY;

}

void ParticleSystem:: setGravityX (double gravity)

{

data.pGravityX = gravity;

}

void ParticleSystem:: setGravityY (double gravity)

{

data.pGravityY = gravity;

}

int ParticleSystem:: getMaxCount () const

{

return data.pMaxCount;

}

void ParticleSystem:: setMaxCount (int count)

{

data.pMaxCount = count;

if (data.pCountOnStart> data.pMaxCount)

data.pCountOnStart = data.pMaxCount;

}

int ParticleSystem:: getCountOnStart () const

{

return data.pCountOnStart;

}

void ParticleSystem:: setCountOnStart (int count)

{

data.pCountOnStart = count;

}

MYSize2D ParticleSystem:: getAppearBoxSize () const

{

return data.pAppearBoxSize;

}

void ParticleSystem:: setAppearBoxSize (MYSize2D box)

{

data.pAppearBoxSize = box;

}

double ParticleSystem:: getRedBegin () const

{

return data.pRedBegin;

}

double ParticleSystem:: getGreenBegin () const

{

return data.pGreenBegin;

}

double ParticleSystem:: getBlueBegin () const

{

return data.pBlueBegin;

}

double ParticleSystem:: getAlphaBegin () const

{

return data.pAlphaBegin;

}

void ParticleSystem:: setRedBegin (double red)

{

data.pRedBegin = red;

}

void ParticleSystem:: setGreenBegin (double green)

{

data.pGreenBegin = green;

}

void ParticleSystem:: setBlueBegin (double blue)

{

data.pBlueBegin = blue;

}

void ParticleSystem:: setAlphaBegin (double alpha)

{

data.pAlphaBegin = alpha;

}

double ParticleSystem:: getRedEnd () const

{

return data.pRedEnd;

}

double ParticleSystem:: getGreenEnd () const

{

return data.pGreenEnd;

}

double ParticleSystem:: getBlueEnd () const

{

return data.pBlueEnd;

}

double ParticleSystem:: getAlphaEnd () const

{

return data.pAlphaEnd;

}

void ParticleSystem:: setRedEnd (double red)

{

data.pRedEnd = red;

}

void ParticleSystem:: setGreenEnd (double green)

{

data.pGreenEnd = green;

}

void ParticleSystem:: setBlueEnd (double blue)

{

data.pBlueEnd = blue;

}

void ParticleSystem:: setAlphaEnd (double alpha)

{

data.pAlphaEnd = alpha;

}

double ParticleSystem:: getRotateAngle () const

{

return data.pAngleRotate;

}

void ParticleSystem:: setRotateAngle (double angle)

{

data.pAngleRotate = angle;

}

double ParticleSystem:: getKFScaleBeginW () const

{

return data.pKFScaleBeginW;

}

double ParticleSystem:: getKFScaleBeginH () const

{

return data.pKFScaleBeginH;

}

void ParticleSystem:: setKFScaleBeginW (double scale)

{

data.pKFScaleBeginW = scale;

}

void ParticleSystem:: setKFScaleBeginH (double scale)

{

data.pKFScaleBeginH = scale;

}

double ParticleSystem:: getKFScaleEndW () const

{

return data.pKFScaleEndW;

}

double ParticleSystem:: getKFScaleEndH () const

{

return data.pKFScaleEndH;

}

void ParticleSystem:: setKFScaleEndW (double scale)

{

data.pKFScaleEndW = scale;

}

void ParticleSystem:: setKFScaleEndH (double scale)

{

data.pKFScaleEndH = scale;

}

double ParticleSystem:: getKFDispersionX () const

{

return data.pKFDispersionX;

}

double ParticleSystem:: getKFDispersionY () const

{

return data.pKFDispersionY;

}

void ParticleSystem:: setKFDispersionX (double disp)

{

data.pKFDispersionX = disp;

}

void ParticleSystem:: setKFDispersionY (double disp)

{

data.pKFDispersionY = disp;

}

wxString ParticleSystem:: getParticleTexFileName () const

{

return data.particleTexFileName;

}

void ParticleSystem:: copyDataFromParticleSystem (ParticleSystem * sys_from)

{

if (! sys_from)

return;

data.pLifeTime = sys_from-> data.pLifeTime;

data.pMaxCount = sys_from-> data.pMaxCount;

data.pCountOnStart = sys_from-> data.pCountOnStart;

data.pGravityX = sys_from-> data.pGravityX;

data.pGravityY = sys_from-> data.pGravityY;

/ / P.speed, dispersion page

data.pMoveSpeedX = sys_from-> data.pMoveSpeedX;

data.pMoveSpeedY = sys_from-> data.pMoveSpeedY;

data.pKFDispersionX = sys_from-> data.pKFDispersionX;

data.pKFDispersionY = sys_from-> data.pKFDispersionY;

/ / P.scale page

data.pKFScaleBeginW = sys_from-> data.pKFScaleBeginW;

data.pKFScaleBeginH = sys_from-> data.pKFScaleBeginH;

data.pKFScaleEndW = sys_from-> data.pKFScaleEndW;

data.pKFScaleEndH = sys_from-> data.pKFScaleEndH;

/ / P.color page

data.pRedBegin = sys_from-> data.pRedBegin;

data.pGreenBegin = sys_from-> data.pGreenBegin;

data.pBlueBegin = sys_from-> data.pBlueBegin;

data.pAlphaBegin = sys_from-> data.pAlphaBegin;

data.pRedEnd = sys_from-> data.pRedEnd;

data.pGreenEnd = sys_from-> data.pGreenEnd;

data.pBlueEnd = sys_from-> data.pBlueEnd;

data.pAlphaEnd = sys_from-> data.pAlphaEnd;

/ / Rotate

data.pAngleRotate = sys_from-> data.pAngleRotate;

/ / Start in, stop in page

data.startDelay = sys_from-> data.startDelay;

data.stopDelay = sys_from-> data.stopDelay;

data.pAppearDelay = sys_from-> data.pAppearDelay;

/ / PS settings page

data.pAppearBoxSize = sys_from-> data.pAppearBoxSize;

data.speedChangeX = sys_from-> data.speedChangeX;

data.speedChangeY = sys_from-> data.speedChangeY;

setX (sys_from-> data.initialX);

setY (sys_from-> data.initialY);

if (sys_from-> data.particleTexFileName == "")

setDefaultParticleTex ();

else

setParticleTex (sys_from-> data.particleTexFileName);

}

bool ParticleSystem:: isRun () const

{

return isRunb;

}

bool ParticleSystem:: isFinished () const

{

return isFinishedb;

}

void ParticleSystem:: start ()

{

isRunb = true;

isFinishedb = false;

restart ();

}

void ParticleSystem:: stop ()

{

isRunb = false;

}

void ParticleSystem:: stopExtra ()

{

isRunb = false;

finish ();

}

void ParticleSystem:: finish ()

{

isFinishedb = true;

currentX = data.initialX;

currentY = data.initialY;

}

void ParticleSystem:: restart ()

{

startInTime = data.startDelay;

stopInTime = data.stopDelay;

timeForNextParticle = data.pAppearDelay;

int count = data.pCountOnStart;

for (int i = 0; i <EXPL_MAX; i + +)

{

if (count> 0)

{

initParticleAtIndex (i);

count -;

}

else

{

pTM [i] = 0;

}

}

}

void ParticleSystem:: initParticleAtIndex (int i)

{

assert (i> = 0 & & i <EXPL_MAX);

pTM [i] = data.pLifeTime;

pX [i] = fmod (rand (), data.pAppearBoxSize.width);

pY [i] = fmod (rand (), data.pAppearBoxSize.height);

double speedDeltaX = fmod (rand (), data.pKFDispersionX * 2 + 1) - data.pKFDispersionX;

pDx [i] = data.pMoveSpeedX + speedDeltaX;

double speedDeltaY = fmod (rand (), data.pKFDispersionY * 2 + 1) - data.pKFDispersionY;

pDy [i] = data.pMoveSpeedY + speedDeltaY;

}

void ParticleSystem:: drawBound ()

{

double appear_w = data.pAppearBoxSize.width;

double appear_h = data.pAppearBoxSize.height;

/ / Draw bound itself

glColor4d (boundColor.Red () / 255.0, boundColor.Green () / 255.0, boundColor.Blue () / 255.0, boundColor.Alpha () / 255.0);

glBegin (GL_POLYGON);

glVertex2d (currentX - BOUND_DIMENSION, currentY - BOUND_DIMENSION);

glVertex2d (currentX + appear_w + BOUND_DIMENSION, currentY - BOUND_DIMENSION);

glVertex2d (currentX + appear_w + BOUND_DIMENSION, currentY + appear_h + BOUND_DIMENSION);

glVertex2d (currentX - BOUND_DIMENSION, currentY + appear_h + BOUND_DIMENSION);

glEnd ();

/ / Draw inner part of bound

glColor4d (boundedRectColor.Red () / 255.0, boundedRectColor.Green () / 255.0, boundedRectColor.Blue () / 255.0,

boundedRectColor.Alpha () / 255.0);

glBegin (GL_POLYGON);

glVertex2d (currentX, currentY);

glVertex2d (currentX + appear_w, currentY);

glVertex2d (currentX + appear_w, currentY + appear_h);

glVertex2d (currentX, currentY + appear_h);

glEnd ();

if (! particleTexPtr)

return;

/ / Draw texture on left-top

double tex_w = particleTexPtr-> getWidth ();

double tex_h = particleTexPtr-> getHeight ();

glEnable (GL_TEXTURE_2D);

GLint binded;

glGetIntegerv (GL_TEXTURE_BINDING_2D, & binded);

glBindTexture (GL_TEXTURE_2D, particleTexPtr-> getName ());

glColor4d (1.0,1.0,1.0,1.0);

double real_tex_w, real_tex_h;

real_tex_w = min (appear_w, tex_w);

real_tex_h = min (appear_h, tex_h);

double real_tex_s, real_tex_t;

real_tex_s = particleTexPtr-> getMaxS () * ((double) real_tex_w) / ((double) tex_w);

real_tex_t = particleTexPtr-> getMaxT () * ((double) real_tex_h) / ((double) tex_h);

glBegin (GL_POLYGON);

glTexCoord2d (0.0, 0.0);

glVertex2d (currentX, currentY);

glTexCoord2d (real_tex_s, 0.0); / / texCoord [0]. x, texCoord [0]. y);

glVertex2d (currentX + real_tex_w, currentY);

glTexCoord2d (real_tex_s, real_tex_t); / / texCoord [1]. x, texCoord [1]. y);

glVertex2d (currentX + real_tex_w, currentY + real_tex_h);

glTexCoord2d (0.0, real_tex_t);

glVertex2d (currentX, currentY + real_tex_h);

glEnd ();

glBindTexture (GL_TEXTURE_2D, binded);

glDisable (GL_TEXTURE_2D);

}

void ParticleSystem:: draw ()

{

if (! particleTexPtr)

return;

if (isFinishedb)

return;

/ / If (int (startInTime * maj_kof)> 0)

if (startInTime> 0.0)

return;

glMatrixMode (GL_MODELVIEW);

MYPoint2D * ptrVert = verCoord;

MYParticleColor * ptrColor = color;

int count = 0;

double progress, x, y, w, h, r, g, b, a;

bool is_rotate = (data.pAngleRotate! = 0.0);

for (int i = 0; i <EXPL_MAX; + + i)

{

progress = pTM [i];

x = pX [i];

y = pY [i];

if (progress> 0.0)

{

progress / = data.pLifeTime;

w = (data.pKFScaleEndW + progress * (data.pKFScaleBeginW - data.pKFScaleEndW)) * particleTexPtr-> getWidth ();

h = (data.pKFScaleEndH + progress * (data.pKFScaleBeginH - data.pKFScaleEndH)) * particleTexPtr-> getHeight ();

if (is_rotate)

{

double real_alpha = fmod (data.pAngleRotate * 360.0 * progress, 360.0);

glPushMatrix ();

glTranslated (x, y, 0.0);

glRotated (real_alpha, 0.0, 0.0, 1.0); / / clock wise direction

x = y = 0.0;

}

x -= w/2.0; / / only CENTERS of particles initially placed in AppearingBox (0.5,0.5 origin)

y -= h/2.0; / / only CENTERS of particles initially placed in AppearingBox (0.5,0.5 origin)

r = data.pRedEnd + progress * (data.pRedBegin - data.pRedEnd);

g = data.pGreenEnd + progress * (data.pGreenBegin - data.pGreenEnd);

b = data.pBlueEnd + progress * (data.pBlueBegin - data.pBlueEnd);

a = data.pAlphaEnd + progress * (data.pAlphaBegin - data.pAlphaEnd);

ptrColor-> r = r; ptrColor-> g = g; ptrColor-> b = b; ptrColor-> a = a; ptrColor + +;

ptrColor-> r = r; ptrColor-> g = g; ptrColor-> b = b; ptrColor-> a = a; ptrColor + +;

ptrColor-> r = r; ptrColor-> g = g; ptrColor-> b = b; ptrColor-> a = a; ptrColor + +;

ptrColor-> r = r; ptrColor-> g = g; ptrColor-> b = b; ptrColor-> a = a; ptrColor + +;

ptrColor-> r = r; ptrColor-> g = g; ptrColor-> b = b; ptrColor-> a = a; ptrColor + +;

ptrColor-> r = r; ptrColor-> g = g; ptrColor-> b = b; ptrColor-> a = a; ptrColor + +;

if (is_rotate)

{

double * m = viewMatrixCache;

glGetDoublev (GL_MODELVIEW_MATRIX, m);

double x2 = x + w;

double y2 = y + h;

double * tp = (double *) ptrVert;

ptrVert-> x = m [0] * x + m [4] * y + m [12]; ptrVert-> y = m [1] * x + m [5] * y + m [13]; ptrVert + +;

ptrVert-> x = m [0] * x2 + m [4] * y + m [12]; ptrVert-> y = m [1] * x2 + m [5] * y + m [13]; ptrVert + +;

ptrVert-> x = m [0] * x2 + m [4] * y2 + m [12]; ptrVert-> y = m [1] * x2 + m [5] * y2 + m [13]; ptrVert + +;

ptrVert-> x = tp [0]; ptrVert-> y = tp [1]; ptrVert + +;

ptrVert-> x = tp [4]; ptrVert-> y = tp [5]; ptrVert + +;

ptrVert-> x = m [0] * x + m [4] * y2 + m [12]; ptrVert-> y = m [1] * x + m [5] * y2 + m [13]; ptrVert + +;

glPopMatrix ();

}

else

{

ptrVert-> x = x; ptrVert-> y = y; ptrVert + +;

ptrVert-> x = x + w; ptrVert-> y = y; ptrVert + +;

ptrVert-> x = x + w; ptrVert-> y = y + h; ptrVert + +;

ptrVert-> x = x; ptrVert-> y = y; ptrVert + +;

ptrVert-> x = x + w; ptrVert-> y = y + h; ptrVert + +;

ptrVert-> x = x; ptrVert-> y = y + h; ptrVert + +;

}

count + +;

}

}

glPushMatrix ();

glTranslated (currentX, currentY, 0.0);

glEnable (GL_TEXTURE_2D);

GLint binded;

glGetIntegerv (GL_TEXTURE_BINDING_2D, & binded);

glBindTexture (GL_TEXTURE_2D, particleTexPtr-> getName ());

glEnableClientState (GL_VERTEX_ARRAY);

glVertexPointer (2, GL_DOUBLE, 0, verCoord);

glEnableClientState (GL_TEXTURE_COORD_ARRAY);

glTexCoordPointer (2, GL_DOUBLE, 0, texCoord);

glEnableClientState (GL_COLOR_ARRAY);

glColorPointer (4, GL_DOUBLE, 0, color);

glDrawArrays (GL_TRIANGLES, 0, count * 6);

glDisableClientState (GL_COLOR_ARRAY);

glDisableClientState (GL_TEXTURE_COORD_ARRAY);

glDisableClientState (GL_VERTEX_ARRAY);

glBindTexture (GL_TEXTURE_2D, binded);

glDisable (GL_TEXTURE_2D);

glPopMatrix ();

}

bool ParticleSystem:: save (TiXmlElement * root_ptr) const

{

TiXmlElement element ("PS");

element.SetAttribute (TEXTURE_ATTR, data.particleTexFileName);

element.SetDoubleAttribute (LIFE_TIME_ATTR, data.pLifeTime);

element.SetDoubleAttribute (APPEAR_DELAY_ATTR, data.pAppearDelay);

element.SetDoubleAttribute (PARTICLE_SPEED_X_ATTR, data.pMoveSpeedX);

element.SetDoubleAttribute (PARTICLE_SPEED_Y_ATTR, data.pMoveSpeedY);

element.SetDoubleAttribute (GRAVITY_X_ATTR, data.pGravityX);

element.SetDoubleAttribute (GRAVITY_Y_ATTR, data.pGravityY);

element.SetAttribute (MAX_COUNT_ATTR, data.pMaxCount);

element.SetAttribute (START_COUNT_ATTR, data.pCountOnStart);

element.SetDoubleAttribute (APPEAR_BOX_W_ATTR, data.pAppearBoxSize.width);

element.SetDoubleAttribute (APPEAR_BOX_H_ATTR, data.pAppearBoxSize.height);

element.SetDoubleAttribute (RED_BEGIN_ATTR, data.pRedBegin);

element.SetDoubleAttribute (RED_END_ATTR, data.pRedEnd);

element.SetDoubleAttribute (GREEN_BEGIN_ATTR, data.pGreenBegin);

element.SetDoubleAttribute (GREEN_END_ATTR, data.pGreenEnd);

element.SetDoubleAttribute (BLUE_BEGIN_ATTR, data.pBlueBegin);

element.SetDoubleAttribute (BLUE_END_ATTR, data.pBlueEnd);

element.SetDoubleAttribute (ALPHA_BEGIN_ATTR, data.pAlphaBegin);

element.SetDoubleAttribute (ALPHA_END_ATTR, data.pAlphaEnd);

element.SetDoubleAttribute (SCALE_BEGIN_W_ATTR, data.pKFScaleBeginW);

element.SetDoubleAttribute (SCALE_BEGIN_H_ATTR, data.pKFScaleBeginH);

element.SetDoubleAttribute (SCALE_END_W_ATTR, data.pKFScaleEndW);

element.SetDoubleAttribute (SCALE_END_H_ATTR, data.pKFScaleEndH);

element.SetDoubleAttribute (DISPERSION_X_ATTR, data.pKFDispersionX);

element.SetDoubleAttribute (DISPERSION_Y_ATTR, data.pKFDispersionY);

element.SetDoubleAttribute (PS_X_ATTR, data.initialX);

element.SetDoubleAttribute (PS_Y_ATTR, data.initialY);

element.SetDoubleAttribute (PS_SPEED_X_ATTR, data.speedChangeX);

element.SetDoubleAttribute (PS_SPEED_Y_ATTR, data.speedChangeY);

element.SetDoubleAttribute (START_DELAY_ATTR, data.startDelay);

element.SetDoubleAttribute (STOP_DELAY_ATTR, data.stopDelay);

element.SetDoubleAttribute (ROTATE_ATTR, data.pAngleRotate);

TiXmlElement * ptr_element = (TiXmlElement *) root_ptr-> InsertEndChild (element);

return ((bool) (ptr_element! = NULL));

}

bool ParticleSystem:: load (TiXmlElement * & element_ptr)

{

TiXmlElement * next_element_ptr = (TiXmlElement *) element_ptr-> FirstChild ("PS");

if (! next_element_ptr)

{

next_element_ptr = (TiXmlElement *) element_ptr-> NextSibling ("PS");

if (! next_element_ptr)

return false;

}

/ / Read version 1.1 parameters

if (next_element_ptr-> QueryIntAttribute (MAX_COUNT_ATTR, & data.pMaxCount)! = TIXML_SUCCESS)

data.pMaxCount = EXPL_MAX;

/ / Read all version parameters (obligatory)

if (next_element_ptr-> QueryIntAttribute (START_COUNT_ATTR, & data.pCountOnStart)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (LIFE_TIME_ATTR, & data.pLifeTime)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (APPEAR_DELAY_ATTR, & data.pAppearDelay)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (PARTICLE_SPEED_X_ATTR, & data.pMoveSpeedX)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (PARTICLE_SPEED_Y_ATTR, & data.pMoveSpeedY)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (GRAVITY_X_ATTR, & data.pGravityX)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (GRAVITY_Y_ATTR, & data.pGravityY)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (APPEAR_BOX_W_ATTR, & data.pAppearBoxSize.width)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (APPEAR_BOX_H_ATTR, & data.pAppearBoxSize.height)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (RED_BEGIN_ATTR, & data.pRedBegin)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (RED_END_ATTR, & data.pRedEnd)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (GREEN_BEGIN_ATTR, & data.pGreenBegin)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (GREEN_END_ATTR, & data.pGreenEnd)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (BLUE_BEGIN_ATTR, & data.pBlueBegin)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (BLUE_END_ATTR, & data.pBlueEnd)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (ALPHA_BEGIN_ATTR, & data.pAlphaBegin)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (ALPHA_END_ATTR, & data.pAlphaEnd)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (SCALE_BEGIN_W_ATTR, & data.pKFScaleBeginW)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (SCALE_BEGIN_H_ATTR, & data.pKFScaleBeginH)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (SCALE_END_W_ATTR, & data.pKFScaleEndW)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (SCALE_END_H_ATTR, & data.pKFScaleEndH)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (DISPERSION_X_ATTR, & data.pKFDispersionX)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (DISPERSION_Y_ATTR, & data.pKFDispersionY)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (PS_X_ATTR, & data.initialX)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (PS_Y_ATTR, & data.initialY)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (PS_SPEED_X_ATTR, & data.speedChangeX)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (PS_SPEED_Y_ATTR, & data.speedChangeY)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (START_DELAY_ATTR, & data.startDelay)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (STOP_DELAY_ATTR, & data.stopDelay)! = TIXML_SUCCESS | |

next_element_ptr-> QueryDoubleAttribute (ROTATE_ATTR, & data.pAngleRotate)! = TIXML_SUCCESS)

return false;

currentX = data.initialX;

currentY = data.initialY;

setParticleTex (next_element_ptr-> Attribute (TEXTURE_ATTR));

element_ptr = next_element_ptr;

return true;

}

void ParticleSystem:: callback (double sec_interval)

{

if (isFinishedb)

return;

/ / Check for startInTime

startInTime -= sec_interval;

/ / If (((int) startInTime * maj_kof)> 0)

if (startInTime> 0.0)

return;

else

startInTime = 0.0;

/ / Change DX DY

currentX + = data.speedChangeX * sec_interval;

currentY + = data.speedChangeY * sec_interval;

/ / Check for the next particle

timeForNextParticle -= sec_interval;

double addParticleTime = 1.0;

if (timeForNextParticle <= 0.0)

{

addParticleTime = timeForNextParticle;

timeForNextParticle = data.pAppearDelay;

}

bool need_to_finish = true;

if (isRunb)

{

need_to_finish = false;

stopInTime -= sec_interval;

/ / If (((int) stopInTime * maj_kof) <= 0)

if (stopInTime <= 0.0)

stop ();

}

/ / Calculate entire number of particles alive

int curr_numof_particles = 0;

for (int i = 0; i <EXPL_MAX; i + +)

if (pTM [i]> 0.0)

+ + Curr_numof_particles;

/ / Process particles

for (int i = 0; i <EXPL_MAX; i + +)

{

pTM [i] -= sec_interval;

if (pTM [i] <= 0.0)

{

if (addParticleTime <= 0.0 & & curr_numof_particles <data.pMaxCount & & isRunb)

{

/ / Add new particle

addParticleTime + = data.pAppearDelay;

+ + Curr_numof_particles;

initParticleAtIndex (i);

}

}

else

{

need_to_finish = false;

pX [i] + = sec_interval * pDx [i];

pY [i] + = sec_interval * pDy [i];

pDx [i] + = sec_interval * data.pGravityX;

pDy [i] + = sec_interval * data.pGravityY;

}

}

if (need_to_finish)

finish ();

}

void ParticleSystem:: setBoundColor (wxColour color)

{

boundColor = color;

}

wxColour ParticleSystem:: getBoundColor ()

{

return boundColor;

}

Додати в блог або на сайт

Цей текст може містити помилки.

Програмування, комп'ютери, інформатика і кібернетика | Диплом
535.4кб. | скачати


Схожі роботи:
Колірні моделі в комп ютерній графіці
Цифрові графічні моделі в комп ютерній графіці
Робота в комп ютерній мережі INTERNET
Засоби візуалізації зображень в комп`ютерній томографії та цифрових рентгенографічних системах
Організація та методика проведення уроку з теми Робота в комп ютерній мережі
Аналіз проблем інформаційної безпеки в комп`ютерній мережі організації підключеної до мережі Інтернтет
Динаміка частинок
Осадження частинок
Синтез нанокристалічних напівпровідникових частинок
© Усі права захищені
написати до нас